Browse Source

Merge pull request #1 from amber-smalltalk/master

Update from original
Sebastian Heidbrink 11 years ago
parent
commit
f753760d36
100 changed files with 16366 additions and 11607 deletions
  1. 3 3
      .travis.yml
  2. 143 0
      API-CHANGES.txt
  3. 140 23
      CHANGELOG
  4. 103 0
      CONTRIBUTING.md
  5. 7 21
      Gruntfile.js
  6. 2 2
      LICENSE
  7. 19 19
      README.md
  8. 18 0
      RELEASING.md
  9. 2 2
      bin/amber
  10. 1 1
      bin/amber.bat
  11. 2 172
      bin/amberc
  12. 1 1
      bin/amberc.bat
  13. 0 611
      bin/amberc.js
  14. 0 27
      bin/release.sh
  15. 0 17
      bin/setversion.sh
  16. 12 2
      bower.json
  17. 2 3
      cli/index.html
  18. 336 223
      cli/js/AmberCli.js
  19. 71 32
      cli/st/AmberCli.st
  20. 920 870
      cli/support/amber-cli.js
  21. 190 0
      cli/support/amberc-cli.js
  22. 549 0
      cli/support/amberc.js
  23. 34 0
      cli/support/release-worker.sh
  24. 9 0
      cli/support/release.sh
  25. 21 0
      cli/support/setversion.sh
  26. 3 3
      css/amber.css
  27. 239 225
      css/helios.css
  28. 841 828
      css/helios.less
  29. 17 7
      grunt/tasks/grunt-amberc.js
  30. 10 15
      grunt/tasks/grunt-peg.js
  31. 2 2
      helios.html
  32. BIN
      images/package.png
  33. 2 3
      index.html
  34. 74 32
      js/Benchfib.js
  35. 259 254
      js/Canvas.js
  36. 384 184
      js/Compiler-AST.js
  37. 285 258
      js/Compiler-Core.js
  38. 55 59
      js/Compiler-Exceptions.js
  39. 336 215
      js/Compiler-IR.js
  40. 483 324
      js/Compiler-Inlining.js
  41. 307 235
      js/Compiler-Interpreter.js
  42. 236 220
      js/Compiler-Semantic.js
  43. 399 235
      js/Compiler-Tests.js
  44. 26 22
      js/Examples.js
  45. 158 148
      js/Helios-Announcements.js
  46. 241 169
      js/Helios-Browser.js
  47. 342 139
      js/Helios-Commands-Browser.js
  48. 175 197
      js/Helios-Commands-Core.js
  49. 485 480
      js/Helios-Commands-Tools.js
  50. 241 176
      js/Helios-Core.js
  51. 355 187
      js/Helios-Debugger.js
  52. 9 3
      js/Helios-Exceptions.js
  53. 1051 0
      js/Helios-Helpers.js
  54. 233 277
      js/Helios-Inspector.js
  55. 195 191
      js/Helios-KeyBindings.js
  56. 188 129
      js/Helios-Layout.js
  57. 189 222
      js/Helios-References.js
  58. 55 53
      js/Helios-Transcript.js
  59. 12 8
      js/Helios-Workspace-Tests.js
  60. 313 237
      js/Helios-Workspace.js
  61. 217 188
      js/IDE.js
  62. 215 233
      js/Kernel-Announcements.js
  63. 287 176
      js/Kernel-Classes.js
  64. 428 162
      js/Kernel-Collections.js
  65. 91 284
      js/Kernel-Exceptions.js
  66. 584 417
      js/Kernel-ImportExport.js
  67. 444 278
      js/Kernel-Infrastructure.js
  68. 231 223
      js/Kernel-Methods.js
  69. 466 274
      js/Kernel-Objects.js
  70. 547 295
      js/Kernel-Tests.js
  71. 22 161
      js/Kernel-Transcript.js
  72. 163 116
      js/SUnit-Tests.js
  73. 203 209
      js/SUnit.js
  74. 87 76
      js/Spaces.js
  75. 7 4
      package.json
  76. 1 1
      st/Benchfib.st
  77. 155 211
      st/Canvas.st
  78. 150 69
      st/Compiler-AST.st
  79. 47 37
      st/Compiler-Core.st
  80. 5 5
      st/Compiler-Exceptions.st
  81. 91 45
      st/Compiler-IR.st
  82. 1 1
      st/Compiler-Inlining.st
  83. 94 127
      st/Compiler-Interpreter.st
  84. 23 6
      st/Compiler-Semantic.st
  85. 65 29
      st/Compiler-Tests.st
  86. 9 9
      st/Examples.st
  87. 15 1
      st/Helios-Announcements.st
  88. 63 14
      st/Helios-Browser.st
  89. 111 1
      st/Helios-Commands-Browser.st
  90. 2 2
      st/Helios-Commands-Core.st
  91. 50 18
      st/Helios-Commands-Tools.st
  92. 96 71
      st/Helios-Core.st
  93. 89 20
      st/Helios-Debugger.st
  94. 13 1
      st/Helios-Exceptions.st
  95. 439 0
      st/Helios-Helpers.st
  96. 8 31
      st/Helios-Inspector.st
  97. 21 6
      st/Helios-KeyBindings.st
  98. 1 1
      st/Helios-Layout.st
  99. 30 29
      st/Helios-References.st
  100. 10 10
      st/Helios-Transcript.st

+ 3 - 3
.travis.yml

@@ -1,6 +1,6 @@
 language: node_js
 node_js:
-  - 0.8
-  - 0.10
+  - "0.8"
+  - "0.10"
 before_script:
-  - npm install -g grunt-cli
+  - npm install -g grunt-cli

+ 143 - 0
API-CHANGES.txt

@@ -1,3 +1,146 @@
+0.12.3 (wip):
+
+* Package Import-Export renamed to Kernel-ImportExport
+* A dozen of methods moved from Object to ProtoObject
+
+* HashedCollection >> at:ifAbsentPut: pushed up to SequenceableCollection
+* HashedCollection >> , is now allowed (removed shouldNotImplement)
+* HashedCollection and Dictionary both subclasses of AssociativeCollection
+* Smalltalk class moved to SmalltalkImage class, Smalltalk is now global var
+* Smalltalk current deprecated in favour of Smalltalk
+* Smalltalk at:[put:] deprecated in favour of Smalltalk globals at:[put:]
+* <smalltalk.ClassName> deprecated in favour of <globals.ClassName>
+
++ CompiledMethod >>
+  + defaultProtocol
++ Behavior >>
+  + compile:protocol:
+  + removeProtocolIfEmpty:
++ Package >>
+  + load
+  + loadFromNamespace:
++ Package class >>
+  + load:
+  + load:fromNamespace:
++ PackageTransport >> load
++ PackageHandler >> load:
++ AmdPackageHandler >> load:
++ Set >> removeAll
++ AssociativeCollection class
++ BucketStore class
++ SmalltalkImage >>
+  + globals
+  + vm
+  + settings
++ Setting class
++ String >>
+  + asSetting
+  + asSettingIfAbsent:
+  + settingValue
+  + settingValueIfAbsent:
+  + settingValue:
++ Smalltalk global variable
+
+- CompiledMethod >>
+  - category: (use #protocol:)
+  - defaultCategory
+- Behavior >> compile:category:
+- HTMLCanvas class >>
+  - browserVersion
+  - isMSIE
+  - isMozilla
+  - isOpera
+  - isWebkit
+
+
+0.12.2:
+
+* Collection >> contains: is deprecated in favor of anySatisfy:
+
+
++ Announcer >> on:doOnce:
++ String >>
+  + uriEncoded
+  + uriDecoded
+  + uriComponentEncoded
+  + uriComponentDecoded
++ Collection >>
+  + removeAll
+  + ifEmpty:ifNotEmpty:
+  + ifNotEmpty:ifEmpty:
+  + anyOne
+  + noneSatisfy:
+  + anySatisfy:
+  + allSatisfy:
+
+
+0.12.0:
+
+* SmalltalkMethodContext.prototype.fillBlock() takes a third 'index' parameter
+* Existing classes moved to new KernelInfrastructure package
+* ImporterExporter
+  * are now StreamExporters
+  * aware of AMD namespaces
+  * support transport types and commit channels
+
+
++ Node >>
+  + nextChild
+  + method
+  + postCopy
+  + isCascadeNode
+  + isLastChild
++ BlockNode >>
+  + nextNode:
+  + nextChild
++ SendNode >>
+  + isCascadeSendNode
+  + shouldBeAliased
++ CompiledMethod >> sendTo:arguments:
++ Array >>
+  + addFirst:
+  + removeLast
++ Number >>
+  + ceiling
+  + floor
+  + asNumber
+  + //
+  + cos
+  + sin
+  + tan
+  + arcCos
+  + arcSin
+  + arcTan
+  + log
+  + log:
+  + raisedTo:
+  + sign
+  + **
+  + ln
+  + e
++ String class >> esc
++ String >>
+  + asMutator
+  + capitalized
+  + isCapitalized
++ JSProxy >> printString
++ Behavior >>
+  + ownProtocols
+  + ownMethods
++ JSStream >> nextPutSendIndexFor:
++ InterfacingObject class
++ Interpreter class
++ DocumentFragmentTag class
++ AbstractExporter class
++ PlatformInterface class
+
+
+- Node >> extent
+- JSStream >> nextPutStatement:with:
+- Smalltalk.installSuperclass()
+- ClassReferenceNode class (now handled via VariableNode)
+
+
 0.11.0:
 
 * AnnouncementSubscription use #valuable: instead of #block: (deprecated)

+ 140 - 23
CHANGELOG

@@ -1,31 +1,148 @@
- 2013 - Release 0.12.0
-===============================
+??th ??? 20?? - Release 0.12.3
+===================================
 
-Some numbers about this release:
+Highlights:
 
-*  commits
-*  committers
-* increasing the number of core committers to 
-*  unit tests added to the kernel
-*  unit tests in total
+* JQuery updated to ~1.10.2; jquery-ui updated to match
+* You can create subclasses of `nil`
+* Amber loads in IE8
+* You can load amber.js asynchronously (it must
+  have id 'amber-path-mapper' in that case)
+* CodeMirror updated to ~3.20.0
 
-Commits
-https://github.com/amber-smalltalk/amber/compare/0.11.0...0.12.0
-Issues
-https://github.com/amber-smalltalk/amber/issues?direction=desc&milestone=8&page=1&sort=updated&state=closed
+Commits: https://github.com/amber-smalltalk/amber/compare/0.12.2...0.12.3
+Issues:  https://github.com/amber-smalltalk/amber/issues?milestone=__&state=closed
 
-* Helios IDE, release candidate
-* Use of require [1] to load amber packages in the browser
-* Restructuring of boot.js, use of the brickz[2] reconfigurable micro composition system
-* Enhanced REPL
+For the most important API related changes see the file API-CHANGES.txt.
 
-[1] http://requirejs.org/
-[2] https://github.com/amber-smalltalk/brikz
 
-For API related changes see the file API-CHANGES.txt.
+03rd December 2013 - Release 0.12.2
+===================================
+
+Highlights:
+
+* Loading Amber in nested pages now possible (via additional `data-libs` attribute of the `<script>` tag which loads `amber.js`)
+* IDE related fixes
+* Contributions Guide
+* Improved Collections
+* Amber Server responds with `not found` instead of `internal server error` if `index.html` could not be found
+
+Commits: https://github.com/amber-smalltalk/amber/compare/0.12.1...0.12.2
+Issues:  https://github.com/amber-smalltalk/amber/issues?milestone=10&state=closed
+
+For the most important API related changes see the file API-CHANGES.txt.
+
+
+14th November 2013 - Release 0.12.1
+===================================
+
+Fixes a bug in Helios preventing class definitions from being compiled
+
+Commits: https://github.com/amber-smalltalk/amber/compare/0.12.0...0.12.1
+Issues:  https://github.com/amber-smalltalk/amber/issues?milestone=9&state=closed
+
+
+11th November 2013 - Release 0.12.0
+===================================
+
+After 3 months of work we are pleased to announce the 0.12.0 release of Amber.
+
+Besides the usual bug fixes a lot of new features have emerged.
+
+The biggest change is the switch to RequireJS to specify Amber package dependencies
+and for loading the packages as AMD modules.
+Amber is now additionally available as Bower [2] component.
+Bower is also used to manage required JavaScript libraries which don't have to be kept
+around in the repository anymore.
+
+The repository layout was restructured to provide a cleaner separation of different Amber parts:
+* Smalltalk code is located in 'st'
+* Compiled Amber packages are located in 'js'
+* Supporting JavaScript code is located in 'support'
+
+Together with the RequireJS changes the specifying their dependencies the Brickz [3]
+reconfigurable micro composition system was introduced.
+This is used for
+
+On the Smalltalk side support has been added for writing exponential numbers of the form 2e5.
+
+Helios (the new IDE) is progressing nicely and has seen a lot of improvements.
+One of the great parts is the new stepping debugger which is also making progress.
+To try Helios, open the helios.html page or
+evaluate in any other amber page `require('amber/helpers').popupHelios()`.
+
+The last enhancements target the commandline compiler which can be used as
+`amberc` (an executable script) or as a Grunt task.
+The following features have been added:
+ * generation of shebang line (#!/usr/bin/env node)
+ * specification of target namespace (`-n` flag; `amd_namespace` option in Grunt)
+ * specification of additional library directories (`-L` flag; `library_dirs` option in Grunt)
+The following features have been removed:
+ * creation of *.deploy.js files (`-d` flag; `deploy` option in Grunt)
+ * optimization passes via Closure compiler (`-o`/`-O` flags; `closure_jar` option in Grunt)
+   The same behavior can be achieved by using specific Grunt tasks
+
+Additionally, the Grunt task now handles the -v/--verbose flag which triggers the same behavior
+as the `verbose` option which can be specified in the Gruntfile.
+
+
+Some numbers about this release (starting from 0.11.0):
 
+* 660 commits
+* 10 committers
+* 66 unit tests added
+* 152 issues were closed
+* 379 unit tests in total
 
 
+Commits: https://github.com/amber-smalltalk/amber/compare/0.11.0...0.12.0
+Issues: https://github.com/amber-smalltalk/amber/issues?direction=desc&milestone=8&page=1&sort=updated&state=closed
+
+For the most important API related changes see the file API-CHANGES.txt.
+
+
+* Installing Amber from NPM
+
+To install Amber from NPM, run
+
+    npm install amber
+
+* Installing Amber from Bower
+
+To install Amber from Bower, run
+
+    bower install amber
+
+* Migration from Amber 0.11.0
+
+First, the loading of JavaScript files must be adapted. The custom loader has been replaced with
+requirejs for loading files in the browser. New loader code is thouroughly
+explained in [4].
+
+After updating the loader part, `.st` files need to be recompiled
+into new AMD `.js` files. During loader changes, a namespace was choosen and will be needed for recompilation.
+
+Go to your directory with `.st` files and issue this from the shell:
+
+```sh
+<path-to-amber>/bin/amberc -l SUnit,Canvas -n <chosen-namespace> -D <path-for-compiled-js-files> *.st
+```
+
+In windows, use `\` as path separator, the rest is identical.
+
+The `-l SUnit,Canvas` is just a general guess, if your code depends on more (or less) non-kernel packages from amber, list them here accordingly.
+
+This migrate scenario only covers simple deployments with your project's code and amber.
+If your project is more complicated, using libraries and packages from multiple sources,
+it is hard to give general advices to migrate - you must do it library by library,
+giving each location its own namespace, and `-L` option of `amberc`
+comes handy when integrating; ask on the mailing list if problems arise.
+
+[1] http://requirejs.org/
+[2] http://bower.io/
+[3] https://github.com/amber-smalltalk/brikz
+[4] https://github.com/amber-smalltalk/amber/wiki/How-to-load-amber
+
 
 09th July 2013 - Release 0.11.0
 ===============================
@@ -54,7 +171,7 @@ evaluate in any other amber page `amber.loadHelios()`.
 The compiler also received some improvements, especially
 regarding message send optimisations and super sends.
 
-Here's the list of commits and closed issues: 
+Here's the list of commits and closed issues:
 https://github.com/amber-smalltalk/amber/compare/0.10.0...0.11.0
 https://github.com/amber-smalltalk/amber/issues?direction=desc&milestone=6&page=1&sort=updated&state=closed
 
@@ -65,7 +182,7 @@ branch on GitHub.
 * Installing Amber from NPM
 
 To install amber from NPM, run
-    
+
     npm install amber
 
 
@@ -169,8 +286,8 @@ Example code and ports
 - Ported ProfStef interactive tutorial, available on Amber homepage but also in examples directory.
 - Included the ESUG presentation as an example also in the examples directory.
 - Several new examples running on Node.js and webOS included, all with Makefiles.
- 
- 
+
+
 Various other things
 
 - Issue tracker on github now used as primary source, closed a bunch of reported issues.

+ 103 - 0
CONTRIBUTING.md

@@ -0,0 +1,103 @@
+Start Contributing by talking about Amber
+=========================================
+
+* Join our [Mailinglist/Google Group](http://groups.google.com/group/amber-lang)
+* Talk to us on [the #amber-lang IRC channel](irc://irc.freenode.net/amber-lang)
+* Follow [@AmberSmalltalk](https://twitter.com/AmberSmalltalk) on Twitter
+* Circle Amber Smalltalk on [Google+](https://plus.google.com/u/0/107038882958653788078) 
+
+
+Filing Issues
+=============
+
+If you think Amber is not working as expected, You can start by asking on IRC or the Mailinglist.
+Please make sure that you have first checked the following guides:
+
+* [Getting Started](https://github.com/amber-smalltalk/amber/wiki/Getting-started)
+* [Writing My First App](https://github.com/amber-smalltalk/amber/wiki/Writing-my-first-app)
+* [How To Load Amber](https://github.com/amber-smalltalk/amber/wiki/How-to-load-amber)
+* [Amber FAQ](https://github.com/amber-smalltalk/amber/wiki/FAQ)
+
+If the issue can not be resolved you should file an issue on the respective tracker.
+
+Before reporting an issue, try to reduce the issue to the bare minimum required to reproduce it.
+This allows us to track down and fix the issue in an easier and faster way.
+
+Additionally, you should give us enough information to reproduce the issue.
+Therefore, include versions of your OS, Amber, Node.js, Grunt, and possibly used libraries as well as sample code.
+If you don't list the exact steps required to reproduce the issue we won't be able to fix it.
+
+Afterwards, report the issue on one of the following trackers:
+
+* [Amber Issues](https://github.com/amber-smalltalk/amber/issues)
+* [Amber Examples Issues](https://github.com/amber-smalltalk/amber-examples/issues)
+* [Amber Website Issues](https://github.com/amber-smalltalk/amber-website/issues)
+
+
+Developing Amber
+================
+
+If you want to get started developing Amber itself there are a few links to get you started
+
+* [The Roadmap](https://github.com/amber-smalltalk/amber/wiki/Roadmap) gives a rough idea about where Amber is heading towards
+* [The Contributions Page](https://github.com/amber-smalltalk/amber/wiki/Contributions) contains some ideas which we would love to integrate into Amber
+* [The Amber FAQ](https://github.com/amber-smalltalk/amber/wiki/FAQ) contains Answers to commonly arising questions
+* [The Amber CookBook](https://github.com/amber-smalltalk/amber/wiki/Amber-cookbook) contains recipies about working with Amber and its IDE
+* [The Amber Porting Guide](https://github.com/amber-smalltalk/amber/wiki/Porting-code-from-other-Smalltalk-dialects) contains information about porting code from other Smalltalk dialects
+* [The Amber JavaScript Guide](https://github.com/amber-smalltalk/amber/wiki/From-smalltalk-to-javascript-and-back) contains information about how Amber and JavaScript are mapped to each other
+
+If you want to get serious with Amber development you should read the [Coding Conventions](https://github.com/amber-smalltalk/amber/wiki/Coding-conventions)
+and check if you have all development dependencies installed (as indicated in [Getting Started](https://github.com/amber-smalltalk/amber/wiki/Getting-started)):
+
+* Git (to get a clone of the repository)
+* Node.js (to run the Amber development server)
+* NPM (to install required Node.js packages)
+* Bower (to install required client side libraries)
+* Grunt-Cli (to compile Amber on the commandline)
+
+ 
+Setup your Amber clone
+----------------------
+
+1. Create a fork of the repository on GitHub
+2. Clone the repository
+3. Run ```npm install```
+4. Run ```bower install``` (requires bower to be installed via ```npm install -g bower```)
+5. Run ```${Amber_DIR}/bin/amber serve```
+
+Now you should be able to commit changes to your computer.
+
+
+Creating a Pull Request
+-----------------------
+
+The Amber development model currently revolves around Pull Requests which are created through GitHub
+
+1. Update to latest Amber master (```git pull```)
+2. Develop your feature or bugfix in a local branch (not in ```master```)
+3. Create unittest for your feature or bugfix (your feature/fix will be integrated a lot faster if unittests are present)
+4. Enhance/fix Amber
+5. Run the unittests
+6. Commit your changes to disk if all tests are green
+7. Try to split your fix into small Git commits if multiple changes are involved (this makes it easier for us to review the changes)
+8. If you created / deleted / moved API, update API-CHANGES.txt appropriately and commit.
+8. Push the changes to your fork on GitHub ```git push <your repo> <your branchname>```
+9. Submit Pull Request (usually for the Amber master branch)
+
+
+Compiling Amber with Grunt
+--------------------------
+
+Amber uses [Grunt.js](http://gruntjs.com/) as build system since version `0.10.0`.
+
+To install Grunt.js v0.4.x on the commandline execute the following commands:
+
+    npm install -g grunt-cli
+
+Make sure that you have installed all required dependencies via `npm` and `bower`.
+Then you can finally compile Amber using the following command:
+
+    cd ${Amber_DIR}
+    grunt
+
+For Windows support check the [Grunt.js on Windows](http://gruntjs.com/frequently-asked-questions#does-grunt-work-on-windows) page.

+ 7 - 21
Gruntfile.js

@@ -16,9 +16,8 @@ module.exports = function(grunt) {
     peg: {
       amber_parser: {
         options: {
-          trackLineAndColumn: true,
           cache: true,
-          export_var: 'smalltalk.parser'
+          export_var: 'globals.SmalltalkParser'
         },
         src: 'support/parser.pegjs',
         dest: 'support/parser.js',
@@ -34,7 +33,7 @@ module.exports = function(grunt) {
         output_dir : 'js',
         src: ['st/Kernel-Objects.st', 'st/Kernel-Classes.st', 'st/Kernel-Methods.st', 'st/Kernel-Collections.st',
               'st/Kernel-Infrastructure.st', 'st/Kernel-Exceptions.st', 'st/Kernel-Transcript.st', 'st/Kernel-Announcements.st',
-              'st/Importer-Exporter.st', 'st/Compiler-Exceptions.st', 'st/Compiler-Core.st', 'st/Compiler-AST.st',
+              'st/Kernel-ImportExport.st', 'st/Compiler-Exceptions.st', 'st/Compiler-Core.st', 'st/Compiler-AST.st',
               'st/Compiler-IR.st', 'st/Compiler-Inlining.st', 'st/Compiler-Semantic.st', 'st/Compiler-Interpreter.st',
               'st/Canvas.st', 'st/SUnit.st', 'st/IDE.st',
               'st/Kernel-Tests.st', 'st/Compiler-Tests.st', 'st/SUnit-Tests.st',
@@ -53,12 +52,6 @@ module.exports = function(grunt) {
         src: ['st/Kernel-Objects.st', 'st/Kernel-Classes.st', 'st/Kernel-Methods.st', 'st/Kernel-Collections.st',
               'st/Kernel-Infrastructure.st', 'st/Kernel-Exceptions.st', 'st/Kernel-Transcript.st', 'st/Kernel-Announcements.st']
       },
-      amber_compiler: {
-        output_dir : 'js',
-        src: ['st/Importer-Exporter.st', 'st/Compiler-Exceptions.st', 'st/Compiler-Core.st', 'st/Compiler-AST.st',
-              'st/Compiler-IR.st', 'st/Compiler-Inlining.st', 'st/Compiler-Semantic.st', 'st/Compiler-Interpreter.st'],
-        output_name: 'Compiler'
-      },
       amber_canvas: {
         output_dir : 'js',
         src: ['st/Canvas.st', 'st/SUnit.st']
@@ -77,28 +70,21 @@ module.exports = function(grunt) {
         src: ['test/Test.st'],
         libraries: [
         'Compiler-Exceptions', 'Compiler-Core', 'Compiler-AST',
-        'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic', 'Compiler-Interpreter', '@parser',
-        'SUnit', 'Importer-Exporter',
+        'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic', 'Compiler-Interpreter', 'parser',
+        'SUnit', 'Kernel-ImportExport',
         'Kernel-Tests', 'Compiler-Tests', 'SUnit-Tests'],
+        main_class: 'NodeTestRunner',
         output_name: 'test/amber_test_runner'
       },
-      amber_dev: {
-        src: [
-              'Compiler-Exceptions.js', 'Compiler-Core.js', 'Compiler-AST.js',
-              'Compiler-IR.js', 'Compiler-Inlining.js', 'Compiler-Semantic.js',
-              'Canvas.js', 'IDE.js', 'SUnit.js',
-              'Kernel-Tests.js', 'Compiler-Tests.js', 'SUnit-Tests.js'],
-        output_name: 'js/amber_dev'
-      },
       amber_cli: {
         output_dir: 'cli/js',
         src: ['cli/st/AmberCli.st'],
         libraries: [
             'Compiler-Exceptions', 'Compiler-Core', 'Compiler-AST',
-            'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic', 'Compiler-Interpreter', '@parser'
+            'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic', 'Compiler-Interpreter', 'parser'
         ],
         main_class: 'AmberCli',
-        output_name: '../../bin/amber-cli',
+        output_name: '../support/amber-cli',
         amd_namespace: 'amber_cli'
       }
     },

+ 2 - 2
LICENSE

@@ -1,5 +1,5 @@
-Copyright (C) 2011-2013 Nicolas Petton <petton.nicolas@gmail.com>
-Copyright (C) 2011-2013 Amber contributors https://github.com/NicolasPetton/amber/contributors
+Copyright (C) 2011-2014 Nicolas Petton <petton.nicolas@gmail.com>
+Copyright (C) 2011-2014 Amber contributors https://github.com/NicolasPetton/amber/contributors
 
 Parts of Amber take ideas from Clamato (http://clamato.net), written by Avi Bryant.
 

+ 19 - 19
README.md

@@ -18,34 +18,34 @@ Some highlights:
 -    Amber can use Javascript libraries and the current IDE is built on [jQuery](http://www.jquery.com)
 -    You can inline Javascript code and there are many ways to interact between Amber and Javascript
 
+Getting Amber
+-------------
 
-License
--------
+Amber is shipped as a [npm](http://npmjs.org) package for its CLI tools and as a [bower](https://github.com/bower/bower) package for the client-side.
 
-Amber is released under the MIT license. All contributions made for inclusion are considered to be under MIT.
+    # Install the CLI tool `amber`
+    npm install -g amber
+    
+    # Load amber via bower in your project
+    bower install amber
+    
+    # Serve amber on localhost:4000
+    amber serve
+
+The [Getting started](https://github.com/amber-smalltalk/amber/wiki/Getting-started) page shows more details on ways to obtain Amber and start a project.
 
 Building Amber
 --------------
 
-Amber uses [Grunt.js](http://gruntjs.com/) as build system since version `0.10.0`.
-
-If you already have Grunt.js v0.3.x installed locally run the following (otherwise ignore these lines):
+This step is only used by people developing Amber itself.
+Please refer to [CONTRIBUTING.md](CONTRIBUTING.md) for further details.
+It explains the Amber development setup and how to contribute.
 
-    cd ${Amber_DIR}
-    npm uninstall grunt
 
-To install Grunt.js v0.4.x on the commandline execute the following commands:
-    
-    npm install -g grunt-cli grunt-init
-    cd ${Amber_DIR}
-    npm install
-
-And finally, compile Amber using the following command:
-
-    cd ${Amber_DIR}
-    grunt
+License
+-------
 
-For Windows support check the [Grunt.js on Windows](http://gruntjs.com/frequently-asked-questions#does-grunt-work-on-windows) page.
+Amber is released under the MIT license. All contributions made for inclusion are considered to be under MIT.
 
 
 More infos

+ 18 - 0
RELEASING.md

@@ -0,0 +1,18 @@
+Release Guide for Amber
+=======================
+
+The following steps are required to make a release of Amber:
+
+1. check that all tests are green
+2. check that the examples are up-to-date
+3. check that `API-CHANGES.txt` is up-to-date
+4. check the `CHANGELOG` file and update the release notes
+5. log in to npm with write access for the Amber package
+6. execute `cli/support/release.sh`
+7. answer the question about the version number used for the release
+8. answer the question about the version number for the upcoming release
+9. merge the created tag into the `stable` branch
+10. update the homepage to point to the latest tag on GitHub
+11. send announcement to mailinglists (Amber, Pharo, what else?)
+12. send announcement on Twitter
+13. send announcement on G+

+ 2 - 2
bin/amber

@@ -1,2 +1,2 @@
-#!/bin/bash
-node `dirname $0`/amber-cli.js $@
+#!/bin/sh
+node `dirname $0`/../cli/support/amber-cli.js $@

+ 1 - 1
bin/amber.bat

@@ -1 +1 @@
-@node "%~dp0\amber-cli.js" %*
+@node "%~dp0\..\cli\support\amber-cli.js" %*

+ 2 - 172
bin/amberc

@@ -1,172 +1,2 @@
-#!/usr/bin/env node
-
-var path = require('path');
-var amberc = require('./amberc.js');
-
-// get parameters passed to the command line script
-// discard the first two parameters which are the node binary and the script name
-var parameters = process.argv.slice(2);
-
-// check if at least one parameter was passed to the script
-if (1 > parameters.length) {
-	print_usage();
-	process.exit();
-}
-
-
-// Get Amber root directory from the location of this script so that
-// we can find the st and js directories etc.
-var amber_dir = path.normalize(path.join(path.dirname(process.argv[1]), '..'));
-
-var compiler = new amberc.Compiler(amber_dir);
-
-var configuration = handle_options(parameters, amber_dir);
-
-compiler.main(configuration);
-
-
-/**
- * Process given program options and update defaults values.
- * Followed by check_for_closure_compiler() and then collect_files().
- */
-function handle_options(optionsArray, amber_dir) {
-	var programName = [];
-	var currentItem = optionsArray.shift();
-	var defaults = amberc.createDefaults(amber_dir);
-
-	while(undefined !== currentItem) {
-		switch(currentItem) {
-			case '-l':
-				defaults.load.push.apply(defaults.load, optionsArray.shift().split(','));
-				break;
-			case '-g':
-				defaults.jsGlobals.push.apply(defaults.jsGlobals, optionsArray.shift().split(','));
-				break;
-			case '-m':
-				defaults.main = optionsArray.shift();
-				break;
-			case '-M':
-				defaults.mainfile = optionsArray.shift();
-				break;
-			case '-n':
-				defaults.amd_namespace = optionsArray.shift();
-				break;
-			case '-D':
-				defaults.output_dir = optionsArray.shift();
-				break;
-			case '-s':
-				defaults.suffix = optionsArray.shift();
-				defaults.suffix_used = defaults.suffix;
-				break;
-			case '-S':
-				defaults.loadsuffix = optionsArray.shift();
-				defaults.suffix_used = defaults.suffix;
-				break;
-			case '-v':
-				defaults.verbose = true;
-				break;
-			case '-h':
-			case '--help':
-			case '?':
-				print_usage();
-				break;
-			default:
-				var fileSuffix = path.extname(currentItem);
-				switch (fileSuffix) {
-					case '.st':
-						defaults.stFiles.push(currentItem);
-						break;
-					case '.js':
-						defaults.jsFiles.push(currentItem);
-						break;
-					default:
-						// Will end up being the last non js/st argument
-						programName.push(currentItem);
-						break;
-				};
-		};
-		currentItem = optionsArray.shift();
-	}
-
-	if(1 < programName.length) {
-		throw new Error('More than one name for ProgramName given: ' + programName);
-	} else {
-		defaults.program = programName[0];
-	}
-	return defaults;
-};
-
-
-// print available flags
-function print_usage() {
-	console.log('Usage: amberc [-l lib1,lib2...] [-i init_file] [-m main_class] [-M main_file]');
-	console.log('          [-o] [-O|-A] [-d] [-s suffix] [-S suffix] [file1 [file2 ...]] [Program]');
-	console.log('');
-	console.log('   amberc compiles Amber files - either separately or into a complete runnable');
-	console.log('   program. If no .st files are listed only a linking stage is performed.');
-	console.log('   Files listed will be handled using the following rules:');
-	console.log('');
-	console.log('   *.js');
-	console.log('     Files are linked (concatenated) in listed order.');
-	console.log('     If not found we look in $AMBER/js/');
-	console.log('');
-	console.log('   *.st');
-	console.log('     Files are compiled into .js files before concatenation.');
-	console.log('     If not found we look in $AMBER/st/.');
-	console.log('');
-	console.log('     NOTE: Each .st file is currently considered to be a fileout of a single class');
-	console.log('     category of the same name as the file!');
-	console.log('');
-	console.log('   If no <Program> is specified each given .st file will be compiled into');
-	console.log('   a matching .js file. Otherwise a <Program>.js file is linked together based on');
-	console.log('   the given options:');
-	console.log('  -l library1,library2');
-	console.log('     Add listed JavaScript libraries in listed order.');
-	console.log('     Libraries are not separated by spaces or end with .js.');
-	console.log('');
-	console.log('  -g jsGlobal1,jsGlobal2');
-	console.log('     Comma separated list of JS global variable names.');
-	console.log('     The names are added to a list containing "window", "document" and others.');
-	console.log('');
-	console.log('  -m main_class');
-	console.log('     Add a call to the class method main_class>>main at the end of <Program>.');
-	console.log('');
-	console.log('  -M main_file');
-	console.log('     Add <main_file> at the end of <Program.js> acting as #main.');
-	console.log('');
-	console.log('  -n amd_namespace');
-	console.log('     Export packages with <amd_namespace> as the require.js namespace.');
-	console.log('     Default value is "amber_core".');
-	console.log('');
-	console.log('  -D');
-	console.log('     Specifies the output directory for all generated .js files.');
-	console.log('     The hierarchy of the input files is not maintaned.');
-	console.log('     If this option is omitted all generated .js files are placed next to their input files');
-	console.log('');
-	console.log('  -s suffix');
-	console.log('     Add <suffix> to compiled .js files. File.st is then compiled into');
-	console.log('     File.<suffix>.js.');
-	console.log('');
-	console.log('  -S suffix');
-	console.log('     Use <suffix> for all libraries accessed using -l. This makes it possible');
-	console.log('     to have multiple flavors of Amber and libraries in the same place.');
-	console.log('');
-	console.log('');
-	console.log('     Example invocations:');
-	console.log('');
-	console.log('     Just compile Kernel-Objects.st to Kernel-Objects.js:');
-	console.log('');
-	console.log('        amberc Kernel-Objects.st');
-	console.log('');
-	console.log('     Compile Hello.st to Hello.js and create complete program called Program.js.');
-	console.log('     Additionally add a call to the class method Hello>>main:');
-	console.log('');
-	console.log('        amberc -m Hello Hello.st Program');
-	console.log('');
-	console.log('     Compile Cat1.st and Cat2.st files into corresponding .js files.');
-	console.log('     Link them with myboot.js and myKernel.js and add myinit.js as custom');
-	console.log('     initializer file. Add main.js last which contains the startup code');
-	console.log('      and merge everything into a complete program named Program.js:');
-	console.log('');
-	console.log('        amberc -M main.js -i myinit.js myboot.js myKernel.js Cat1.st Cat2.st Program');
-};
+#!/bin/sh
+node `dirname $0`/../cli/support/amberc-cli.js $@

+ 1 - 1
bin/amberc.bat

@@ -1 +1 @@
-@node "%~dp0\amberc" %*
+@node "%~dp0\..\cli\support\amberc-cli.js" %*

+ 0 - 611
bin/amberc.js

@@ -1,611 +0,0 @@
-/**
- * This is a "compiler" for Amber code.
- * Put the following code into compiler.js:
- *     var amberc = require('amberc');
- *     var compiler = new amberc.Compiler('path/to/amber', ['/optional/path/to/compiler.jar]);
- *     compiler.main();
- *
- * Execute 'node compiler.js' without arguments or with -h / --help for help.
- */
-
-/**
- * Map the async filter function onto array and evaluate callback, once all have finished.
- * Taken from: http://howtonode.org/control-flow-part-iii
- */
-function async_map(array, filter, callback) {
-	if (0 === array.length) {
-		callback(null, null);
-		return;
-	}
-	var counter = array.length;
-	var new_array = [];
-	array.forEach(function (item, index) {
-		filter(item, function (err, result) {
-			if (err) { callback(err); return; }
-			new_array[index] = result;
-			counter--;
-			if (counter === 0) {
-				callback(null, new_array);
-			}
-		});
-	});
-}
-
-
-/**
- * Always evaluates the callback parameter.
- * Used by Combo blocks to always call the next function,
- * even if all of the other functions did not run.
- */
-function always_resolve(callback) {
-	callback();
-}
-
-
-/**
- * Helper for concatenating Amber generated AMD modules.
- * The produced output can be exported and run as an independent program.
- *
- * var concatenator = createConcatenator();
- * concatenator.start(); // write the required AMD define header
- * concatenator.add(module1);
- * concatenator.addId(module1_ID);
- * //...
- * concatenator.finish("//some last code");
- * var concatenation = concatenator.toString();
- * // The variable concatenation contains the concatenated result
- * // which can either be stored in a file or interpreted with eval().
- */
-function createConcatenator () {
-	return {
-		elements: [],
-		ids: [],
-		add: function () {
-			this.elements.push.apply(this.elements, arguments);
-		},
-		addId: function () {
-			this.ids.push.apply(this.ids, arguments);
-		},
-		forEach: function () {
-			this.elements.forEach.apply(this.elements, arguments);
-		},
-		start: function () {
-			this.add(
-				'var define = (' + require('amdefine') + ')(), requirejs = define.require;',
-				'define("amber_vm/browser-compatibility", [], {});'
-			);
-		},
-		finish: function (realWork) {
-			this.add(
-				'define("amber_vm/_init", ["amber_vm/smalltalk","' + this.ids.join('","') + '"], function (smalltalk) {',
-				'smalltalk.initialize();',
-				realWork,
-				'});',
-				'requirejs("amber_vm/_init");'
-			);
-		},
-		toString: function () {
-			return this.elements.join('\n');
-		}
-	};
-}
-
-/**
- * Combine several async functions and evaluate callback once all of them have finished.
- * Taken from: http://howtonode.org/control-flow
- */
-function Combo(callback) {
-	this.callback = callback;
-	this.items = 0;
-	this.results = [];
-}
-
-Combo.prototype = {
-	add: function () {
-		var self = this,
-		id = this.items;
-		this.items++;
-		return function () {
-			self.check(id, arguments);
-		};
-	},
-	check: function (id, arguments) {
-		this.results[id] = Array.prototype.slice.call(arguments);
-		this.items--;
-		if (this.items == 0) {
-			this.callback.apply(this, this.results);
-		}
-	}
-};
-
-var path = require('path'),
-	util = require('util'),
-	fs = require('fs'),
-	exec = require('child_process').exec;
-
-/**
- * AmberC constructor function.
- * amber_dir: points to the location of an amber installation
- * closure_jar: location of compiler.jar (can be left undefined)
- */
-function AmberC(amber_dir) {
-	this.amber_dir = amber_dir;
-	this.kernel_libraries = ['@boot', '@smalltalk', '@nil', '@_st', 'Kernel-Objects', 'Kernel-Classes', 'Kernel-Methods',
-							'Kernel-Collections', 'Kernel-Infrastructure', 'Kernel-Exceptions', 'Kernel-Transcript',
-							'Kernel-Announcements'];
-	this.compiler_libraries = this.kernel_libraries.concat(['@parser', 'Importer-Exporter', 'Compiler-Exceptions',
-							'Compiler-Core', 'Compiler-AST', 'Compiler-Exceptions', 'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic']);
-}
-
-
-/**
- * Default values.
- */
-var createDefaults = function(amber_dir, finished_callback){
-	if (undefined === amber_dir) {
-		throw new Error('createDefaults() function needs a valid amber_dir parameter');
-	}
-
-	return {
-		'load': [],
-		'main': undefined,
-		'mainfile': undefined,
-		'stFiles': [],
-		'jsFiles': [],
-		'jsGlobals': [],
-		'amd_namespace': 'amber_core',
-		'suffix': '',
-		'loadsuffix': '',
-		'suffix_used': '',
-		'libraries': [],
-		'compile': [],
-		'compiled': [],
-		'program': undefined,
-		'output_dir': undefined,
-		'verbose': false,
-		'finished_callback': finished_callback
-	};
-};
-
-
-/**
- * Main function for executing the compiler.
- * If check_configuration_ok() returns successfully the configuration is set on the current compiler
- * instance and check_for_closure_compiler() gets called.
- * The last step is to call collect_files().
- */
-AmberC.prototype.main = function(configuration, finished_callback) {
-	console.time('Compile Time');
-	if (undefined !== finished_callback) {
-		configuration.finished_callback = finished_callback;
-	}
-
-	if (configuration.amd_namespace.length == 0) {
-		configuration.amd_namespace = 'amber_core';
-	}
-
-	console.ambercLog = console.log;
-	if (false === configuration.verbose) {
-		console.log = function() {};
-	}
-
-	if (this.check_configuration_ok(configuration)) {
-		this.defaults = configuration;
-		this.defaults.smalltalk = {}; // the evaluated compiler will be stored in this variable (see create_compiler)
-		this.collect_files(this.defaults.stFiles, this.defaults.jsFiles)
-	}
-};
-
-
-/**
- * Check if the passed in configuration object has sufficient/nonconflicting values
- */
-AmberC.prototype.check_configuration_ok = function(configuration) {
-	if (undefined === configuration) {
-		throw new Error('AmberC.check_configuration_ok(): missing configuration object');
-	}
-
-	if (0 === configuration.jsFiles.length && 0 === configuration.stFiles.lenght) {
-		throw new Error('AmberC.check_configuration_ok(): no files to compile/link specified in configuration object');
-	}
-	return true;
-};
-
-
-/**
- * Check if the file given as parameter exists in the local directory or in $AMBER/js/.
- * '.js' is appended first.
- *
- * @param filename name of a file without '.js' prefix
- * @param callback gets called on success with path to .js file as parameter
- */
-AmberC.prototype.resolve_js = function(filename, callback) {
-	var special = filename[0] == "@";
-	if (special) {
-		filename = filename.slice(1);
-	}
-	var baseName = path.basename(filename, '.js');
-	var jsFile = baseName + this.defaults.loadsuffix + '.js';
-	var amberJsFile = path.join(this.amber_dir, special?'support':'js', jsFile);
-	console.log('Resolving: ' + jsFile);
-	fs.exists(jsFile, function(exists) {
-		if (exists) {
-			callback(jsFile);
-		} else {
-			fs.exists(amberJsFile, function(exists) {
-				if (exists) {
-					callback(amberJsFile);
-				} else {
-					throw(new Error('JavaScript file not found: ' + jsFile));
-				}
-			});
-		}
-	});
-};
-
-
-/**
- * Collect libraries and Smalltalk files looking
- * both locally and in $AMBER/js and $AMBER/st.
- * Followed by resolve_libraries().
- */
-AmberC.prototype.collect_files = function(stFiles, jsFiles) {
-	var self = this;
-	var collected_files = new Combo(function() {
-		self.resolve_libraries();
-	});
-	if (0 !== stFiles.length) {
-		self.collect_st_files(stFiles, collected_files.add());
-	}
-	if (0 !== jsFiles.length) {
-		self.collect_js_files(jsFiles, collected_files.add());
-	}
-};
-
-
-/**
- * Resolve st files given by stFiles and add them to defaults.compile.
- * Respective categories get added to defaults.compile_categories.
- * callback is evaluated afterwards.
- */
-AmberC.prototype.collect_st_files = function(stFiles, callback) {
-	var defaults = this.defaults;
-	var self = this;
-	var collected_st_files = new Combo(function() {
-		Array.prototype.slice.call(arguments).forEach(function(data) {
-			var stFile = data[0];
-			defaults.compile.push(stFile);
-		});
-		callback();
-	});
-
-	stFiles.forEach(function(stFile) {
-		var _callback = collected_st_files.add();
-		console.log('Checking: ' + stFile);
-		var amberStFile = path.join(self.amber_dir, 'st', stFile);
-		fs.exists(stFile, function(exists) {
-			if (exists) {
-				_callback(stFile);
-			} else {
-				console.log('Checking: ' + amberStFile);
-				fs.exists(amberStFile, function(exists) {
-					if (exists) {
-						_callback(amberStFile);
-					} else {
-						throw(new Error('Smalltalk file not found: ' + amberStFile));
-					}
-				});
-			}
-		});
-	});
-};
-
-
-/**
- * Resolve js files given by jsFiles and add them to defaults.libraries.
- * callback is evaluated afterwards.
- */
-AmberC.prototype.collect_js_files = function(jsFiles, callback) {
-	var self = this;
-	var collected_js_files = new Combo(function() {
-		Array.prototype.slice.call(arguments).forEach(function(file) {
-			self.defaults.libraries.push(file[0]);
-		});
-		callback();
-	});
-
-	jsFiles.forEach(function(jsFile) {
-		self.resolve_js(jsFile, collected_js_files.add());
-	});
-};
-
-
-/**
- * Resolve kernel and compiler files.
- * Followed by resolve_init().
- */
-AmberC.prototype.resolve_libraries = function() {
-	// Resolve libraries listed in this.kernel_libraries
-	var self = this;
-	var all_resolved = new Combo(function(resolved_kernel_files, resolved_compiler_files) {
-		self.create_compiler(resolved_compiler_files[0]);
-	});
-	this.resolve_kernel(all_resolved.add());
-	this.resolve_compiler(all_resolved.add());
-};
-
-
-/**
- * Resolve .js files needed by kernel
- * callback is evaluated afterwards.
- */
-AmberC.prototype.resolve_kernel = function(callback) {
-	var self = this;
-	var kernel_files = this.kernel_libraries.concat(this.defaults.load);
-	var kernel_resolved = new Combo(function() {
-		var foundLibraries = [];
-		Array.prototype.slice.call(arguments).forEach(function(file) {
-			if (undefined !== file[0]) {
-				foundLibraries.push(file[0]);
-			}
-		});
-		// boot.js and Kernel files need to be used first
-		// otherwise the global smalltalk object is undefined
-		self.defaults.libraries = foundLibraries.concat(self.defaults.libraries);
-		callback(null);
-	});
-
-	kernel_files.forEach(function(file) {
-		self.resolve_js(file, kernel_resolved.add());
-	});
-
-	always_resolve(kernel_resolved.add());
-};
-
-
-/**
- * Resolve .js files needed by compiler.
- * callback is evaluated afterwards with resolved files as argument.
- */
-AmberC.prototype.resolve_compiler = function(callback) {
-	// Resolve compiler libraries
-	var compiler_files = this.compiler_libraries.concat(this.defaults.load);
-	var compiler_resolved = new Combo(function() {
-		var compilerFiles = [];
-		Array.prototype.slice.call(arguments).forEach(function(file) {
-			if (undefined !== file[0]) {
-				compilerFiles.push(file[0]);
-			}
-		});
-		callback(compilerFiles);
-	});
-	var self = this
-	compiler_files.forEach(function(file) {
-		self.resolve_js(file, compiler_resolved.add());
-	});
-
-	always_resolve(compiler_resolved.add());
-};
-
-
-/**
- * Read all .js files needed by compiler and eval() them.
- * The finished Compiler gets stored in defaults.smalltalk.
- * Followed by compile().
- */
-AmberC.prototype.create_compiler = function(compilerFilesArray) {
-	var self = this;
-	var compiler_files = new Combo(function() {
-		var builder = createConcatenator();
-		builder.add('(function() {');
-		builder.start();
-
-		Array.prototype.slice.call(arguments).forEach(function(data) {
-			// data is an array where index 0 is the error code and index 1 contains the data
-			builder.add(data[1]);
-			// matches and returns the "module_id" string in the AMD definition: define("module_id", ...)
-			var match = ('' + data[1]).match(/^define\("([^"]*)"/);
-			if (match) {
-				builder.addId(match[1]);
-			}
-		});
-		// store the generated smalltalk env in self.defaults.smalltalk
-		builder.finish('self.defaults.smalltalk = smalltalk;');
-		builder.add('})();');
-		eval(builder.toString());
-		console.log('Compiler loaded');
-		self.defaults.smalltalk.ErrorHandler._setCurrent_(self.defaults.smalltalk.RethrowErrorHandler._new());
-
-		if(0 != self.defaults.jsGlobals.length) {
-			var jsGlobalVariables = self.defaults.smalltalk.globalJsVariables;
-			jsGlobalVariables.push.apply(jsGlobalVariables, self.defaults.jsGlobals);
-		}
-
-		self.compile();
-	});
-
-	compilerFilesArray.forEach(function(file) {
-		console.log('Loading file: ' + file);
-		fs.readFile(file, compiler_files.add());
-	});
-};
-
-
-/**
- * Compile all given .st files by importing them.
- * Followed by category_export().
- */
-AmberC.prototype.compile = function() {
-	console.log('Compiling collected .st files')
-	// import .st files
-	var self = this;
-	var imports = new Combo(function() {
-		Array.prototype.slice.call(arguments).forEach(function(code) {
-			if (undefined !== code[0]) {
-				// get element 0 of code since all return values are stored inside an array by Combo
-				self.defaults.smalltalk.Importer._new()._import_(code[0]._stream());
-			}
-		});
-		self.category_export();
-	});
-
-	this.defaults.compile.forEach(function(stFile) {
-		var callback = imports.add();
-		if (/\.st/.test(stFile)) {
-			console.ambercLog('Importing: ' + stFile);
-			fs.readFile(stFile, 'utf8', function(err, data) {
-				if (!err)
-					callback(data);
-				else
-					throw new Error('Could not import: ' + stFile);
-			});
-		}
-	});
-	always_resolve(imports.add());
-};
-
-
-/**
- * Export compiled categories to JavaScript files.
- * Followed by verify().
- */
-AmberC.prototype.category_export = function() {
-	var defaults = this.defaults;
-	var self = this;
-	// export categories as .js
-	async_map(defaults.compile, function(stFile, callback) {
-		var category = path.basename(stFile, '.st');
-		var jsFilePath = defaults.output_dir;
-		if (undefined === jsFilePath) {
-			jsFilePath = path.dirname(stFile);
-		}
-		var jsFile = category + defaults.suffix_used + '.js';
-		jsFile = path.join(jsFilePath, jsFile);
-		defaults.compiled.push(jsFile);
-		var smalltalk = defaults.smalltalk;
-		var pluggableExporter = smalltalk.PluggableExporter;
-		var packageObject = smalltalk.Package._named_(category);
-		packageObject._transport()._namespace_(defaults.amd_namespace);
-		fs.writeFile(jsFile, smalltalk.String._streamContents_(function (stream) {
-			smalltalk.AmdExporter._new()._exportPackage_on_(packageObject, stream); }), function(err) {
-				callback(null, null);
-			});
-	}, function(err, result){
-		self.verify();
-	});
-};
-
-
-/**
- * Verify if all .st files have been compiled.
- * Followed by compose_js_files().
- */
-AmberC.prototype.verify = function() {
-	console.log('Verifying if all .st files were compiled');
-	var self = this;
-	// copy array
-	var compiledFiles = this.defaults.compiled.slice(0);
-
-	async_map(compiledFiles,
-		function(file, callback) {
-			fs.exists(file, function(exists) {
-				if (exists)
-					callback(null, null);
-				else
-					throw(new Error('Compilation failed of: ' + file));
-			});
-		}, function(err, result) {
-			self.compose_js_files();
-	});
-};
-
-
-/**
- * Synchronous function.
- * Concatenates compiled JavaScript files into one file in the correct order.
- * The name of the produced file is given by defaults.program (set by the last commandline option).
- */
-AmberC.prototype.compose_js_files = function() {
-	var defaults = this.defaults;
-	var self = this;
-	var programFile = defaults.program;
-	if (undefined === programFile) {
-		return;
-	}
-	if (undefined !== defaults.output_dir) {
-		programFile = path.join(defaults.output_dir, programFile);
-	}
-
-	var program_files = [];
-	if (0 !== defaults.libraries.length) {
-		console.log('Collecting libraries: ' + defaults.libraries);
-		program_files.push.apply(program_files, defaults.libraries);
-	}
-
-	if (0 !== defaults.compiled.length) {
-		var compiledFiles = defaults.compiled.slice(0);
-
-		console.log('Collecting compiled files: ' + compiledFiles);
-		program_files.push.apply(program_files, compiledFiles);
-	}
-
-	console.ambercLog('Writing program file: %s.js', programFile);
-
-	var fileStream = fs.createWriteStream(programFile + defaults.suffix_used + '.js');
-	fileStream.on('error', function(error) {
-		fileStream.end();
-		console.ambercLog(error);
-	});
-
-	fileStream.on('close', function(){
-		return;
-	});
-
-	var builder = createConcatenator();
-	builder.add('#!/usr/bin/env node');
-	builder.start();
-
-	program_files.forEach(function(file) {
-		if(fs.existsSync(file)) {
-			console.log('Adding : ' + file);
-			var buffer = fs.readFileSync(file);
-			// matches and returns the "module_id" string in the AMD define: define("module_id", ...)
-			var match = buffer.toString().match(/^define\("([^"]*)"/);
-			if (match /*&& match[1].slice(0,9) !== "amber_vm/"*/) {
-				builder.addId(match[1]);
-			}
-			builder.add(buffer);
-		} else {
-			fileStream.end();
-			throw(new Error('Can not find file ' + file));
-		}
-	});
-
-	var mainFunctionOrFile = '';
-
-	if (undefined !== defaults.main) {
-		console.log('Adding call to: %s>>main', defaults.main);
-		mainFunctionOrFile += 'smalltalk.' + defaults.main + '._main();';
-	}
-
-	if (undefined !== defaults.mainfile && fs.existsSync(defaults.mainfile)) {
-		console.log('Adding main file: ' + defaults.mainfile);
-		mainFunctionOrFile += '\n' + fs.readFileSync(defaults.mainfile);
-	}
-
-	builder.finish(mainFunctionOrFile);
-
-	console.log('Writing...');
-	builder.forEach(function (element) {
-		fileStream.write(element);
-		fileStream.write('\n');
-	});
-	console.log('Done.');
-	fileStream.end();
-};
-
-
-module.exports.Compiler = AmberC;
-module.exports.createDefaults = createDefaults;
-module.exports.Combo = Combo;
-module.exports.map = async_map;

+ 0 - 27
bin/release.sh

@@ -1,27 +0,0 @@
-#!/bin/sh
-cd `dirname "$0"`/..
-echo git reset --hard
-echo git checkout master
-echo -n "Which version are you going to publish [0 to skip]? "
-VER=`head -n 1`
-if [ "$VER" = "0" ]; then :; else
-	echo "Publishing version $VER"
-	bin/setversion.sh "$VER"
-	cp package.json package.json.bak
-	sed -e 's@/amber.git.*"@/amber.git#'"$VER"'"@' package.json.bak >package.json
-	rm package.json.bak
-	echo git commit -a -m "Release version $VER"
-	echo git tag -a "$VER"
-	echo bower upload
-	echo npm upload
-fi
-echo -n "Which version are you going to work on? "
-VERF=`head -n 1`
-VER="${VER}-pre"
-echo "Setting version $VER"
-bin/setversion.sh "$VER"
-cp package.json package.json.bak
-sed -e 's@/amber.git.*"@/amber.git"@' package.json.bak >package.json
-rm package.json.bak
-echo git commit -a -m "Working on $VERF"
-echo git push --tags

+ 0 - 17
bin/setversion.sh

@@ -1,17 +0,0 @@
-#!/bin/sh
-cd `dirname "$0"`
-cd ../st
-rm -f *.js
-cp Kernel-Infrastructure.st Kernel-Infrastructure.st.bak
-sed -e "/^version\$/,/^\! \!\$/ s/\^ '[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\(-pre\)\{0,1\}'\$/^ '$1'/" Kernel-Infrastructure.st.bak >Kernel-Infrastructure.st
-rm Kernel-Infrastructure.st.bak
-cd ..
-bin/amberc -d -l Kernel-Objects,Kernel-Collections Kernel-Infrastructure.st
-cd st
-mv *.js ../js
-cd ..
-for F in *.json; do
-  cp $F $F.bak
-  sed -e 's/"version": "[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\(-pre\)\{0,1\}"/"version": "'"$1"'"/' $F.bak >$F
-  rm $F.bak
-done

+ 12 - 2
bower.json

@@ -1,6 +1,6 @@
 {
   "name": "amber",
-  "version": "0.12.0-pre",
+  "version": "0.13.0-pre",
   "main": "support/amber.js",
   "ignore": [
     "**/.*",
@@ -8,5 +8,15 @@
     "bower_components",
     "test",
     "tests"
-  ]
+  ],
+  "dependencies": {
+    "jquery": "~1.10.2",
+    "jquery-ui": "~1.10.3",
+    "bootstrap": "http://getbootstrap.com/2.3.2/assets/bootstrap.zip",
+    "jquery-tabby": "git://github.com/alanhogan/Tabby",
+    "es5-shim": "~2.1.0",
+    "codemirror": "~3.20.0",
+    "showdown": "~0.3.1",
+    "require-css": "~0.0.8"
+  }
 }

+ 2 - 3
cli/index.html

@@ -22,9 +22,8 @@
         ["amber/devel",
             "amber_cli/AmberCli" ],
         function (smalltalk) {
-            smalltalk.defaultAmdNamespace = 'amber_cli';
-            smalltalk.initialize();
-            smalltalk.Browser._openOn_(smalltalk.AmberCli);
+            smalltalk.initialize({'transport.defaultAmdNamespace': 'amber_cli'});
+            smalltalk.globals.Browser._openOn_(smalltalk.AmberCli);
         }
     );
     </script> 

File diff suppressed because it is too large
+ 336 - 223
cli/js/AmberCli.js


+ 71 - 32
cli/st/AmberCli.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'AmberCli'!
+Smalltalk createPackage: 'AmberCli'!
 Object subclass: #AmberCli
 	instanceVariableNames: ''
 	package: 'AmberCli'!
@@ -126,11 +126,12 @@ Adding new commandline parameters to `FileServer` is as easy as adding a new sin
 !FileServer methodsFor: 'accessing'!
 
 basePath
-	^basePath ifNil: ['./']
+	^basePath ifNil: [self class defaultBasePath]
 !
 
 basePath: aString
-	basePath := aString
+	basePath := aString.
+	self validateBasePath.
 !
 
 fallbackPage
@@ -168,8 +169,11 @@ username: aUsername
 !FileServer methodsFor: 'initialization'!
 
 checkDirectoryLayout
-	(fs existsSync: self basePath, 'index.html') ifFalse: [
-		console warn: 'Warning: project directory does not contain index.html'].
+	(fs existsSync:	(self withBasePath: 'index.html')) ifFalse: [
+		console warn: 'Warning: project directory does not contain index.html.'.
+		console warn: '    You can specify the directory containing index.html with --base-path.'.
+		console warn: '    You can also specify a page to be served by default,'.
+		console warn: '    for all paths that do not map to a file, with --fallback-page.'].
 	(fs existsSync: self basePath, 'st') ifFalse: [
 		console warn: 'Warning: project directory is missing an "st" directory'].
 	(fs existsSync: self basePath, 'js') ifFalse: [
@@ -226,6 +230,18 @@ require: aModuleString
 	^require value: aModuleString
 !
 
+validateBasePath
+	"The basePath must be an existing directory. "
+	fs stat: self basePath then: [ :err :stat | err
+		ifNil: [ stat isDirectory ifFalse: [ console warn: 'Warning: --base-path parameter ' , self basePath , ' is not a directory.' ]]
+		ifNotNil: [ console warn: 'Warning: path at --base-path parameter ' , self basePath , ' does not exist.'  ]].
+!
+
+withBasePath: aBaseRelativePath
+	"return a file path which is relative to the basePath."
+	^	path join: self basePath with: aBaseRelativePath
+!
+
 writeData: data toFileNamed: aFilename
 	console log: aFilename
 ! !
@@ -234,12 +250,14 @@ writeData: data toFileNamed: aFilename
 
 handleGETRequest: aRequest respondTo: aResponse
 	| uri filename |
-	uri := (url parse: aRequest url) pathname.
-	filename := path join: self basePath with: uri.
+	uri := url parse: aRequest url.
+	filename := path join: self basePath with: uri pathname.
 	fs exists: filename do: [:aBoolean |
 		aBoolean
 			ifFalse: [self respondNotFoundTo: aResponse]
-			ifTrue: [self respondFileNamed: filename to: aResponse]]
+			ifTrue: [(fs statSync: filename) isDirectory
+				ifTrue: [self respondDirectoryNamed: filename from: uri to: aResponse]
+				ifFalse: [self respondFileNamed: filename to: aResponse]]]
 !
 
 handleOPTIONSRequest: aRequest respondTo: aResponse
@@ -298,18 +316,22 @@ respondCreatedTo: aResponse
 		end.
 !
 
+respondDirectoryNamed: aDirname from: aUrl to: aResponse
+	(aUrl pathname endsWith: '/')
+		ifTrue: [self respondFileNamed: aDirname, 'index.html' to: aResponse]
+		ifFalse: [self respondRedirect: aUrl pathname, '/', (aUrl search ifNil: ['']) to: aResponse]
+!
+
 respondFileNamed: aFilename to: aResponse
 	| type filename |
 
 	filename := aFilename.
-	(fs statSync: aFilename) isDirectory ifTrue: [
-		filename := filename, 'index.html'].
 
 	fs readFile: filename do: [:ex :file |
 		ex notNil 
 			ifTrue: [
 				console log: filename, ' does not exist'.
-				self respondInternalErrorTo: aResponse]
+				self respondNotFoundTo: aResponse]
 			ifFalse: [
 				type := self class mimeTypeFor: filename.
 				type = 'application/javascript'
@@ -337,8 +359,13 @@ respondNotCreatedTo: aResponse
 respondNotFoundTo: aResponse
 	self fallbackPage isNil ifFalse: [^self respondFileNamed: self fallbackPage to: aResponse].
 	aResponse 
-		writeHead: 404 options: #{'Content-Type' -> 'text/plain'};
-		write: '404 Not found';
+		writeHead: 404 options: #{'Content-Type' -> 'text/html'};
+		write: '<html><body><p>404 Not found</p>';
+		write: '<p>Did you forget to put an index.html file into the directory which is served by "bin/amber serve"? To solve this you can:<ul>';
+		write: '<li>create an index.html in the served directory.</li>';
+		write: '<li>can also specify the location of a page to be served whenever path does not resolve to a file with the "--fallback-page" option.</li>';
+		write: '<li>change the directory to be served with the "--base-path" option.</li>';
+		write: '</ul></p></body></html>';
 		end
 !
 
@@ -346,6 +373,12 @@ respondOKTo: aResponse
 	aResponse
 		writeHead: 200 options: #{'Content-Type' -> 'text/plain'. 'Access-Control-Allow-Origin' -> '*'};
 		end.
+!
+
+respondRedirect: aString to: aResponse
+	aResponse
+		writeHead: 303 options: #{'Location' -> aString};
+		end.
 ! !
 
 !FileServer methodsFor: 'starting'!
@@ -386,6 +419,10 @@ commandLineSwitches
 	^switches
 !
 
+defaultBasePath
+	^ './'
+!
+
 defaultHost
 	^'127.0.0.1'
 !
@@ -913,6 +950,14 @@ prompt
 
 !Repl methodsFor: 'actions'!
 
+clearScreen
+	| esc cls |
+	esc := String fromCharCode: 27.
+	cls := esc, '[2J', esc, '[0;0f'.
+	process stdout write: cls.
+	interface prompt
+!
+
 close
 	process stdin destroy
 !
@@ -936,11 +981,16 @@ eval: buffer on: anObject
 			result := Compiler new evaluateExpression: buffer on: anObject]
 		catch: [:e |
 			e isSmalltalkError
-			    ifTrue: [ErrorHandler new handleError: e]
-			    ifFalse: [process stdout write: e jsStack]]].
+			    ifTrue: [ e resignal ]
+			    ifFalse: [ process stdout write: e jsStack ]]].
 	^ result
 !
 
+printWelcome
+	Transcript show: 'Welcome to Amber version ', Smalltalk current version, ' (NodeJS ', process versions node, ').'.
+	Transcript show: 'Type :q to exit.'; cr.
+!
+
 setPrompt
 	interface setPrompt: self prompt
 ! !
@@ -983,18 +1033,12 @@ assignNewVariable: buffer do: aBlock
 	^ self parseAssignment: buffer do: [ :name :expr || varName value |
 		varName := name ifNil: [self nextResultName].
 		session := self addVariableNamed: varName to: session.
-		value := self eval: varName, ' := ', (expr ifNil: [buffer]) on: session.
+		[ value := self eval: varName, ' := ', (expr ifNil: [buffer]) on: session ]
+			on: Error
+			do: [ :e | ErrorHandler new logError: e. value := nil].
 		aBlock value: varName value: value]
 !
 
-clearScreen
-	| esc cls |
-	esc := String fromCharCode: 27.
-	cls := esc, '[2J', esc, '[0;0f'.
-	process stdout write: cls.
-	interface prompt
-!
-
 encapsulateVariable: aString withValue: anObject in: aClass
 	"Add getter and setter for given variable to session."
 	| compiler |
@@ -1022,7 +1066,7 @@ instanceVariableNamesFor: aClass
 !
 
 isIdentifier: aString
-	^ aString match: '^[a-z_]\w+$' asRegexp
+	^ aString match: '^[a-z_]\w*$' asRegexp
 !
 
 isVariableDefined: aString
@@ -1047,8 +1091,8 @@ parseAssignment: aString do: aBlock
 	| assignment |
 	assignment := (aString tokenize: ':=') collect: [:s | s trimBoth].
 	^ (assignment size = 2 and: [self isIdentifier: assignment first])
-		ifTrue: [aBlock value: assignment first value: assignment last]
-		ifFalse: [aBlock value: nil value: nil]
+		ifTrue: [ aBlock value: assignment first value: assignment last ]
+		ifFalse: [ aBlock value: nil value: nil ]
 !
 
 presentResultNamed: varName withValue: value
@@ -1056,11 +1100,6 @@ presentResultNamed: varName withValue: value
 	interface prompt
 !
 
-printWelcome
-	Transcript show: 'Welcome to Amber version ', Smalltalk current version, ' (NodeJS ', process versions node, ').'.
-	Transcript show: 'Type :q to exit.'; cr.
-!
-
 processLine: buffer
 	"Processes lines entered through the readline interface."
 	| show |

File diff suppressed because it is too large
+ 920 - 870
cli/support/amber-cli.js


+ 190 - 0
cli/support/amberc-cli.js

@@ -0,0 +1,190 @@
+#!/usr/bin/env node
+
+var path = require('path');
+var amberc = require('./amberc.js');
+
+// get parameters passed to the command line script
+// discard the first two parameters which are the node binary and the script name
+var parameters = process.argv.slice(2);
+
+// check if at least one parameter was passed to the script
+if (1 > parameters.length) {
+	print_usage();
+	process.exit();
+}
+
+
+// Get Amber root directory from the location of this script so that
+// we can find the st and js directories etc.
+var amber_dir = path.normalize(path.join(path.dirname(process.argv[1]), '..', '..'));
+
+var compiler = new amberc.Compiler(amber_dir);
+
+var configuration = handle_options(parameters);
+
+compiler.main(configuration);
+
+
+/**
+ * Process given program options and update defaults values.
+ * Followed by check_for_closure_compiler() and then collect_files().
+ */
+function handle_options(optionsArray) {
+	var programName = [];
+	var currentItem = optionsArray.shift();
+	var defaults = amberc.createDefaultConfiguration();
+
+	while(undefined !== currentItem) {
+		switch(currentItem) {
+			case '-l':
+				defaults.load.push.apply(defaults.load, optionsArray.shift().split(','));
+				break;
+			case '-L':
+				defaults.jsLibraryDirs.push.apply(defaults.jsLibraryDirs, optionsArray.shift().split(','));
+				break;
+			case '-g':
+				defaults.jsGlobals.push.apply(defaults.jsGlobals, optionsArray.shift().split(','));
+				break;
+			case '-m':
+				defaults.main = optionsArray.shift();
+				break;
+			case '-M':
+				defaults.mainfile = optionsArray.shift();
+				break;
+			case '-n':
+				defaults.amd_namespace = optionsArray.shift();
+				break;
+			case '-D':
+				defaults.output_dir = optionsArray.shift();
+				break;
+			case '-s':
+				defaults.suffix = optionsArray.shift();
+				defaults.suffix_used = defaults.suffix;
+				break;
+			case '-S':
+				defaults.loadsuffix = optionsArray.shift();
+				defaults.suffix_used = defaults.suffix;
+				break;
+			case '-v':
+				defaults.verbose = true;
+				break;
+			case '-h':
+			case '--help':
+			case '?':
+				print_usage();
+				break;
+			default:
+				var fileSuffix = path.extname(currentItem);
+				switch (fileSuffix) {
+					case '.st':
+						defaults.stFiles.push(currentItem);
+						break;
+					case '.js':
+						defaults.jsFiles.push(currentItem);
+						break;
+					default:
+						// Will end up being the last non js/st argument
+						programName.push(currentItem);
+						break;
+				}
+		}
+		currentItem = optionsArray.shift();
+	}
+
+	if(1 < programName.length) {
+		throw new Error('More than one name for ProgramName given: ' + programName);
+	} else {
+		defaults.program = programName[0];
+	}
+	return defaults;
+}
+
+
+// print available flags
+function print_usage() {
+	var usage = [
+		'Usage: amberc [-l lib1,lib2...] [-g jsGlobal1,jsGlobla2] [-m main_class] [-M main_file]',
+		'          [-n namespace] [-D output_dir] [-v] [-s suffix] [-S suffix] [file1 [file2 ...]] [Program]',
+		'',
+		'   amberc compiles Amber files - either separately or into a complete runnable',
+		'   program. If no .st files are listed only a linking stage is performed.',
+		'   Files listed will be handled using the following rules:',
+		'',
+		'   *.js',
+		'     Files are linked (concatenated) in listed order.',
+		'     If not found we look in $AMBER/js/',
+		'',
+		'   *.st',
+		'     Files are compiled into .js files before concatenation.',
+		'     If not found we look in $AMBER/st/.',
+		'',
+		'     NOTE: Each .st file is currently considered to be a fileout of a single class',
+		'     category of the same name as the file!',
+		'',
+		'   If no <Program> is specified each given .st file will be compiled into',
+		'   a matching .js file. Otherwise a <Program>.js file is linked together based on',
+		'   the given options:',
+		'',
+		'  -l library1,library2',
+		'     Add listed JavaScript libraries in listed order.',
+		'     Libraries are not separated by spaces or end with .js.',
+		'',
+		'  -L directory1,directory2',
+		'     Add listed directories to the library search path.',
+		'     The order of processing is:',
+		'     1. current directory',
+		'     2. directories specified by -L',
+		'     3. $AMBER',
+		'',
+		'  -g jsGlobal1,jsGlobal2',
+		'     Comma separated list of JS global variable names.',
+		'     The names are added to a list containing "window", "document" and others.',
+		'',
+		'  -m main_class',
+		'     Add a call to the class method main_class>>main at the end of <Program>.',
+		'',
+		'  -M main_file',
+		'     Add <main_file> at the end of <Program.js> acting as #main.',
+		'',
+		'  -n amd_namespace',
+		'     Export packages with <amd_namespace> as the require.js namespace.',
+		'     Default value is "amber_core".',
+		'',
+		'  -v',
+		'     Produce a more verbose output.',
+		'',
+		'  -D',
+		'     Specifies the output directory for all generated .js files.',
+		'     The hierarchy of the input files is not maintaned.',
+		'     If this option is omitted all generated .js files are placed next to their input files',
+		'',
+		'  -s suffix',
+		'     Add <suffix> to compiled .js files. File.st is then compiled into',
+		'     File.<suffix>.js.',
+		'',
+		'  -S suffix',
+		'     Use <suffix> for all libraries accessed using -l. This makes it possible',
+		'     to have multiple flavors of Amber and libraries in the same place.',
+		'',
+		'',
+		'     Example invocations:',
+		'',
+		'     Just compile Kernel-Objects.st to Kernel-Objects.js:',
+		'',
+		'        amberc Kernel-Objects.st',
+		'',
+		'     Compile Hello.st to Hello.js and create complete program called Program.js.',
+		'     Additionally add a call to the class method Hello>>main:',
+		'',
+		'        amberc -m Hello Hello.st Program',
+		'',
+		'     Compile Cat1.st and Cat2.st files into corresponding .js files.',
+		'     Link them with myboot.js and myKernel.js',
+		'     and merge everything into a complete program named Program.js:',
+		'',
+		'        amberc -M main.js myboot.js myKernel.js Cat1.st Cat2.st Program',
+	];
+	usage.forEach(function (line) {
+        console.log(line);
+	});
+}

+ 549 - 0
cli/support/amberc.js

@@ -0,0 +1,549 @@
+/**
+ * This is a "compiler" for Amber code.
+ * Put the following code into compiler.js:
+ *     var amberc = require('amberc');
+ *     var compiler = new amberc.Compiler('path/to/amber');
+ *     var options = amberc.createDefaults();
+ *     // edit options entries
+ *     compiler.main(options);
+ */
+
+/**
+ * Helper for concatenating Amber generated AMD modules.
+ * The produced output can be exported and run as an independent program.
+ *
+ * var concatenator = createConcatenator();
+ * concatenator.start(); // write the required AMD define header
+ * concatenator.add(module1);
+ * concatenator.addId(module1_ID);
+ * //...
+ * concatenator.finish("//some last code");
+ * var concatenation = concatenator.toString();
+ * // The variable concatenation contains the concatenated result
+ * // which can either be stored in a file or interpreted with eval().
+ */
+function createConcatenator () {
+	return {
+		elements: [],
+		ids: [],
+		add: function () {
+			this.elements.push.apply(this.elements, arguments);
+		},
+		addId: function () {
+			this.ids.push.apply(this.ids, arguments);
+		},
+		forEach: function () {
+			this.elements.forEach.apply(this.elements, arguments);
+		},
+		start: function () {
+			this.add(
+				'var define = (' + require('amdefine') + ')(null, function (id) { throw new Error("Dependency not found: " +  id); }), requirejs = define.require;',
+				'define("amber_vm/browser-compatibility", [], {});'
+			);
+		},
+		finish: function (realWork) {
+			this.add(
+				'define("amber_vm/_init", ["amber_vm/smalltalk", "amber_vm/globals", "' + this.ids.join('","') + '"], function (vm, globals) {',
+				'vm.initialize();',
+				realWork,
+				'});',
+				'requirejs("amber_vm/_init");'
+			);
+		},
+		toString: function () {
+			return this.elements.join('\n');
+		}
+	};
+}
+
+
+var path = require('path'),
+	fs = require('fs'),
+	Promise = require('es6-promise').Promise;
+
+/**
+ * AmberCompiler constructor function.
+ * amber_dir: points to the location of an amber installation
+ */
+function AmberCompiler(amber_dir) {
+	if (undefined === amber_dir || !fs.existsSync(amber_dir)) {
+		throw new Error('amber_dir needs to be a valid directory');
+	}
+
+	this.amber_dir = amber_dir;
+	this.kernel_libraries = ['boot', 'smalltalk', 'globals', 'nil', '_st', 'Kernel-Objects', 'Kernel-Classes', 'Kernel-Methods',
+							'Kernel-Collections', 'Kernel-Infrastructure', 'Kernel-Exceptions', 'Kernel-Transcript',
+							'Kernel-Announcements'];
+	this.compiler_libraries = this.kernel_libraries.concat(['parser', 'Kernel-ImportExport', 'Compiler-Exceptions',
+							'Compiler-Core', 'Compiler-AST', 'Compiler-Exceptions', 'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic']);
+}
+
+
+/**
+ * Default values.
+ */
+var createDefaultConfiguration = function() {
+	return {
+		'load': [],
+		'main': undefined,
+		'mainfile': undefined,
+		'stFiles': [],
+		'jsFiles': [],
+		'jsGlobals': [],
+		'amd_namespace': 'amber_core',
+		'suffix': '',
+		'loadsuffix': '',
+		'suffix_used': '',
+		'libraries': [],
+		'jsLibraryDirs': [],
+		'compile': [],
+		'compiled': [],
+		'program': undefined,
+		'output_dir': undefined,
+		'verbose': false
+	};
+};
+
+
+/**
+ * Main function for executing the compiler.
+ * If check_configuration_ok() returns successfully
+ * the configuration is used to trigger the following compilation steps.
+ */
+AmberCompiler.prototype.main = function(configuration, finished_callback) {
+	console.time('Compile Time');
+
+	if (configuration.amd_namespace.length === 0) {
+		configuration.amd_namespace = 'amber_core';
+	}
+
+	if (undefined !== configuration.jsLibraryDirs) {
+		configuration.jsLibraryDirs.push(path.join(this.amber_dir, 'js'));
+		configuration.jsLibraryDirs.push(path.join(this.amber_dir, 'support'));
+	}
+
+	console.ambercLog = console.log;
+	if (false === configuration.verbose) {
+		console.log = function() {};
+	}
+
+	// the evaluated compiler will be stored in this variable (see create_compiler)
+	configuration.vm = {};
+	configuration.globals = {};
+	configuration.kernel_libraries = this.kernel_libraries;
+	configuration.compiler_libraries = this.compiler_libraries;
+	configuration.amber_dir = this.amber_dir;
+
+	check_configuration(configuration)
+	.then(collect_st_files)
+	.then(collect_js_files)
+	.then(resolve_kernel)
+	.then(create_compiler)
+	.then(compile)
+	.then(category_export)
+	.then(verify)
+	.then(compose_js_files)
+	.then(function () {
+		console.timeEnd('Compile Time');
+	}, function(error) {
+		console.error(error);
+	})
+	.then(function () {
+		console.log = console.ambercLog;
+		finished_callback && finished_callback();
+	});
+};
+
+
+/**
+ * Check if the passed in configuration object has sufficient/nonconflicting values.
+ * Returns a Promise which resolves into the configuration object.
+ */
+function check_configuration(configuration) {
+	return new Promise(function(resolve, reject) {
+		if (undefined === configuration) {
+			reject(Error('AmberCompiler.check_configuration_ok(): missing configuration object'));
+		}
+
+		if (0 === configuration.jsFiles.length && 0 === configuration.stFiles.length) {
+			reject(Error('AmberCompiler.check_configuration_ok(): no files to compile/link specified in configuration object'));
+		}
+
+		resolve(configuration);
+	});
+};
+
+
+/**
+ * Check if the file given as parameter exists in any of the following directories:
+ *  1. current local directory
+ *  2. configuration.jsLibraryDirs
+ *  3. $AMBER/js/
+ *  3. $AMBER/support/
+ *
+ * @param filename name of a file without '.js' prefix
+ * @param configuration the main amberc configuration object
+ */
+function resolve_js(filename, configuration) {
+	var baseName = path.basename(filename, '.js');
+	var jsFile = baseName + configuration.loadsuffix + '.js';
+	return resolve_file(jsFile, configuration.jsLibraryDirs);
+};
+
+
+/**
+ * Check if the file given as parameter exists in any of the following directories:
+ *  1. current local directory
+ *  2. $AMBER/
+ *
+ * @param filename name of a .st file
+ * @param configuration the main amberc configuration object
+ */
+function resolve_st(filename, configuration) {
+	return resolve_file(filename, [configuration.amber_dir]);
+};
+
+
+/**
+ * Resolve the location of a file given as parameter filename.
+ * First check if the file exists at given location,
+ * then check in each of the directories specified in parameter searchDirectories.
+ */
+function resolve_file(filename, searchDirectories) {
+	return new Promise(function(resolve, reject) {
+		console.log('Resolving: ' + filename);
+		fs.exists(filename, function(exists) {
+			if (exists) {
+				resolve(filename);
+			} else {
+				var alternativeFile = '';
+				// check for filename in any of the given searchDirectories
+				var found = searchDirectories.some(function(directory) {
+					alternativeFile = path.join(directory, filename);
+					return fs.existsSync(alternativeFile);
+				});
+				if (found) {
+					resolve(alternativeFile);
+				} else {
+					reject(Error('File not found: ' + alternativeFile));
+				}
+			}
+		});
+	});
+};
+
+
+/**
+ * Resolve st files given by stFiles and add them to configuration.compile.
+ * Returns a Promise which resolves into the configuration object.
+ */
+function collect_st_files(configuration) {
+	return Promise.all(
+		configuration.stFiles.map(function(stFile) {
+			return resolve_st(stFile, configuration);
+		})
+	)
+	.then(function(data) {
+		configuration.compile = configuration.compile.concat(data);
+		return configuration;
+	});
+}
+
+
+/**
+ * Resolve js files given by jsFiles and add them to configuration.libraries.
+ * Returns a Promise which resolves into the configuration object.
+ */
+function collect_js_files(configuration) {
+	return Promise.all(
+		configuration.jsFiles.map(function(file) {
+			return resolve_js(file, configuration);
+		})
+	)
+	.then(function(data) {
+		configuration.libraries = configuration.libraries.concat(data);
+		return configuration;
+	});
+}
+
+
+/**
+ * Resolve .js files needed by kernel.
+ * Returns a Promise which resolves into the configuration object.
+ */
+function resolve_kernel(configuration) {
+	var kernel_files = configuration.kernel_libraries.concat(configuration.load);
+	return Promise.all(
+		kernel_files.map(function(file) {
+			return resolve_js(file, configuration);
+		})
+	)
+	.then(function(data) {
+		// boot.js and Kernel files need to be used first
+		// otherwise the global objects 'vm' and 'globals' are undefined
+		configuration.libraries = data.concat(configuration.libraries);
+		return configuration;
+	});
+}
+
+
+/**
+ * Resolve .js files needed by compiler, read and eval() them.
+ * The finished Compiler gets stored in configuration.{vm,globals}.
+ * Returns a Promise object which resolves into the configuration object.
+ */
+function create_compiler(configuration) {
+	var compiler_files = configuration.compiler_libraries.concat(configuration.load);
+	return Promise.all(
+		compiler_files.map(function(file) {
+			return resolve_js(file, configuration);
+		})
+	)
+	.then(function(compilerFilesArray) {
+		return Promise.all(
+			compilerFilesArray.map(function(file) {
+				return new Promise(function(resolve, reject) {
+					console.log('Loading file: ' + file);
+					fs.readFile(file, function(err, data) {
+						if (err)
+							reject(err);
+						else
+							resolve(data);
+					});
+				});
+			})
+		)
+	})
+	.then(function(files) {
+		var builder = createConcatenator();
+		builder.add('(function() {');
+		builder.start();
+
+		files.forEach(function(data) {
+			// data is an array where index 0 is the error code and index 1 contains the data
+			builder.add(data);
+			// matches and returns the "module_id" string in the AMD definition: define("module_id", ...)
+			var match = ('' + data).match(/^define\("([^"]*)"/);
+			if (match) {
+				builder.addId(match[1]);
+			}
+		});
+		// store the generated smalltalk env in configuration.{vm,globals}
+		builder.finish('configuration.vm = vm; configuration.globals = globals;');
+		builder.add('})();');
+
+		eval(builder.toString());
+
+		console.log('Compiler loaded');
+
+		configuration.globals.ErrorHandler._register_(configuration.globals.RethrowErrorHandler._new());
+
+		if(0 !== configuration.jsGlobals.length) {
+			var jsGlobalVariables = configuration.vm.globalJsVariables;
+			jsGlobalVariables.push.apply(jsGlobalVariables, configuration.jsGlobals);
+		}
+
+		return configuration;
+	});
+}
+
+
+/**
+ * Compile all given .st files by importing them.
+ * Returns a Promise object that resolves into the configuration object.
+ */
+function compile(configuration) {
+	// return function which does the actual work
+	// and use the compile function to reference the configuration object
+	return Promise.all(
+		configuration.compile.map(function(stFile) {
+			return new Promise(function(resolve, reject) {
+				if (/\.st/.test(stFile)) {
+					console.ambercLog('Reading: ' + stFile);
+					fs.readFile(stFile, 'utf8', function(err, data) {
+						if (!err)
+							resolve(data);
+						else
+							reject(Error('Could not read: ' + stFile));
+					});
+				}
+			});
+		})
+	)
+	.then(function(fileContents) {
+		console.log('Compiling collected .st files');
+		// import/compile content of .st files
+		return Promise.all(
+			fileContents.map(function(code) {
+				return new Promise(function(resolve, reject) {
+					var importer = configuration.globals.Importer._new();
+					try {
+						importer._import_(code._stream());
+						resolve(true);
+					} catch (ex) {
+						reject(Error("Compiler error in section:\n" +
+							importer._lastSection() + "\n\n" +
+							"while processing chunk:\n" +
+							importer._lastChunk() + "\n\n" +
+							(ex._messageText && ex._messageText() || ex.message || ex))
+						);
+					}
+				});
+			})
+		);
+	})
+	.then(function () {
+		return configuration;
+	});
+}
+
+
+/**
+ * Export compiled categories to JavaScript files.
+ * Returns a Promise() that resolves into the configuration object.
+ */
+function category_export(configuration) {
+	return Promise.all(
+		configuration.compile.map(function(stFile) {
+			return new Promise(function(resolve, reject) {
+				var category = path.basename(stFile, '.st');
+				var jsFilePath = configuration.output_dir;
+				if (undefined === jsFilePath) {
+					jsFilePath = path.dirname(stFile);
+				}
+				var jsFile = category + configuration.suffix_used + '.js';
+				jsFile = path.join(jsFilePath, jsFile);
+				configuration.compiled.push(jsFile);
+				var smalltalkGlobals = configuration.globals;
+				var packageObject = smalltalkGlobals.Package._named_(category);
+				packageObject._transport()._namespace_(configuration.amd_namespace);
+				fs.writeFile(jsFile, smalltalkGlobals.String._streamContents_(function (stream) {
+					smalltalkGlobals.AmdExporter._new()._exportPackage_on_(packageObject, stream);
+				}), function(err) {
+					if (err)
+						reject(err);
+					else
+						resolve(true);
+				});
+			});
+		})
+	)
+	.then(function() {
+		return configuration;
+	});
+}
+
+
+/**
+ * Verify if all .st files have been compiled.
+ * Returns a Promise() that resolves into the configuration object.
+ */
+function verify(configuration) {
+	console.log('Verifying if all .st files were compiled');
+	return Promise.all(
+		configuration.compiled.map(function(file) {
+			return new Promise(function(resolve, reject) {
+				fs.exists(file, function(exists) {
+					if (exists)
+						resolve(true);
+					else
+						reject(Error('Compilation failed of: ' + file));
+				});
+			});
+		})
+	)
+	.then(function() {
+		return configuration;
+	});
+}
+
+
+/**
+ * Synchronous function.
+ * Concatenates compiled JavaScript files into one file in the correct order.
+ * The name of the produced file is given by configuration.program.
+ * Returns a Promise which resolves into the configuration object.
+ */
+function compose_js_files(configuration) {
+	return new Promise(function(resolve, reject) {
+		var programFile = configuration.program;
+		if (undefined === programFile) {
+			reject(configuration);
+		}
+		if (undefined !== configuration.output_dir) {
+			programFile = path.join(configuration.output_dir, programFile);
+		}
+
+		var program_files = [];
+		if (0 !== configuration.libraries.length) {
+			console.log('Collecting libraries: ' + configuration.libraries);
+			program_files.push.apply(program_files, configuration.libraries);
+		}
+
+		if (0 !== configuration.compiled.length) {
+			var compiledFiles = configuration.compiled.slice(0);
+
+			console.log('Collecting compiled files: ' + compiledFiles);
+			program_files.push.apply(program_files, compiledFiles);
+		}
+
+		console.ambercLog('Writing program file: %s.js', programFile);
+
+		var fileStream = fs.createWriteStream(programFile + configuration.suffix_used + '.js');
+		fileStream.on('error', function(error) {
+			fileStream.end();
+			console.ambercLog(error);
+			reject(error);
+		});
+
+		fileStream.on('close', function(){
+			resolve(configuration);
+		});
+
+		var builder = createConcatenator();
+		builder.add('#!/usr/bin/env node');
+		builder.start();
+
+		program_files.forEach(function(file) {
+			if(fs.existsSync(file)) {
+				console.log('Adding : ' + file);
+				var buffer = fs.readFileSync(file);
+				// matches and returns the "module_id" string in the AMD define: define("module_id", ...)
+				var match = buffer.toString().match(/^define\("([^"]*)"/);
+				if (match /*&& match[1].slice(0,9) !== "amber_vm/"*/) {
+					builder.addId(match[1]);
+				}
+				builder.add(buffer);
+			} else {
+				fileStream.end();
+				reject(Error('Can not find file ' + file));
+			}
+		});
+
+		var mainFunctionOrFile = '';
+
+		if (undefined !== configuration.main) {
+			console.log('Adding call to: %s>>main', configuration.main);
+			mainFunctionOrFile += 'globals.' + configuration.main + '._main();';
+		}
+
+		if (undefined !== configuration.mainfile && fs.existsSync(configuration.mainfile)) {
+			console.log('Adding main file: ' + configuration.mainfile);
+			mainFunctionOrFile += '\nvar smalltalk = vm; // backward compatibility\n' + fs.readFileSync(configuration.mainfile);
+		}
+
+		builder.finish(mainFunctionOrFile);
+
+		console.log('Writing...');
+		builder.forEach(function (element) {
+			fileStream.write(element);
+			fileStream.write('\n');
+		});
+		console.log('Done.');
+		fileStream.end();
+	});
+}
+
+
+module.exports.Compiler = AmberCompiler;
+module.exports.createDefaultConfiguration = createDefaultConfiguration;

+ 34 - 0
cli/support/release-worker.sh

@@ -0,0 +1,34 @@
+#!/bin/sh
+
+# ATTENTION: Be logged into npm before running this script,
+# as a user with write access to amber npm package.
+
+git reset --hard
+git checkout master
+git clean -d -x -f
+npm install
+echo -n "Which version are you going to publish [0 to skip]? "
+VER=`head -n 1`
+if [ "$VER" = "0" ]; then :; else
+	echo "Publishing version $VER"
+	cli/support/setversion.sh "$VER"
+	cp package.json package.json.bak
+	sed -e 's@/amber.git.*"@/amber.git#'"$VER"'"@' package.json.bak >package.json
+	rm package.json.bak
+	git add package.json
+	git commit -a -m "Release version $VER"
+	git tag -a "$VER" -m "Release version $VER"
+# bower does not publish explicitly but implictly via semver tag
+	echo npm publish
+fi
+echo -n "Which version are you going to work on? "
+VERF=`head -n 1`
+VER="${VERF}-pre"
+echo "Setting version $VER"
+cli/support/setversion.sh "$VER"
+cp package.json package.json.bak
+sed -e 's@/amber.git.*"@/amber.git"@' package.json.bak >package.json
+rm package.json.bak
+git add package.json
+git commit -a -m "Working on $VERF"
+git push --tags

+ 9 - 0
cli/support/release.sh

@@ -0,0 +1,9 @@
+#!/bin/sh
+
+# ATTENTION: Be logged into npm before running this script,
+# as a user with write access to amber npm package.
+
+cd `dirname "$0"`
+cp release-worker.sh /tmp
+cd ../..
+exec sh /tmp/release-worker.sh

+ 21 - 0
cli/support/setversion.sh

@@ -0,0 +1,21 @@
+#!/bin/sh
+
+VERSION=$1
+cd `dirname "$0"`/../..
+AMBER_BASE=`pwd`
+
+cd $AMBER_BASE/st
+# replace version number
+cp Kernel-Infrastructure.st Kernel-Infrastructure.st.bak
+sed -e "/^version\$/,/^\! \!\$/ s/\^ '[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\(-pre\)\{0,1\}'\$/^ '$VERSION'/" Kernel-Infrastructure.st.bak >Kernel-Infrastructure.st
+rm Kernel-Infrastructure.st.bak
+
+# compile Kernel-Infrastructure
+cd $AMBER_BASE
+bin/amberc -D js -l Kernel-Objects,Kernel-Collections st/Kernel-Infrastructure.st
+# set version in all json files (bower, npm)
+for F in *.json; do
+  cp $F $F.bak
+  sed -e 's/"version": "[0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\(-pre\)\{0,1\}"/"version": "'"$VERSION"'"/' $F.bak >$F
+  rm $F.bak
+done

+ 3 - 3
css/amber.css

@@ -241,7 +241,7 @@ body.amberBody {
 .amberTool textarea,
 .amberTool input {
     border: 0 none;
-    font-family:  "DejaVu Sans", Helvetica, sans;
+    font-family:  "DejaVu Sans", Helvetica, sans-serif;
     line-height: 1.3em;
     font-size: 11px;
     position: relative;
@@ -250,7 +250,7 @@ body.amberBody {
 
 .amberTool .CodeMirror {
     border: 0 none;
-    font-family:  "DejaVu Sans", Helvetica, sans;
+    font-family:  "DejaVu Sans", Helvetica, sans-serif;
     font-size: 11px;
     line-height: 1.3em;
     height: 100%;
@@ -262,7 +262,7 @@ body.amberBody {
 }
 
 .amberTool .CodeMirror-scroll pre {
-    font-family: "DejaVu Sans", Helvetica, sans;
+    font-family: "DejaVu Sans", Helvetica, sans-serif;
 }
 
 .amberTool .amber_clear {

+ 239 - 225
css/helios.css

@@ -15,76 +15,76 @@ html[xmlns] .clearfix {
 * html .clearfix {
   height: 1%;
 }
-#helios {
-    font-size: 11px;
-    font-family: "Lucida Grande", helvetica, arial, sans;
-    background: #eee;
+.cm-s-helios.CodeMirror {
+  font-family: Menlo, Monaco, Consolas, Inconsolata, "Lucida Console", Courier, monospace;
+  line-height: 16px;
+  font-size: 13px;
+}
+.cm-s-helios .CodeMirror-gutter.stops {
+  width: 20px;
+}
+.cm-s-helios .highlighted.CodeMirror-linebackground {
+  background-color: #ffffaa;
+}
+.cm-s-helios .CodeMirror-gutter-elt .stop {
+  width: 16px;
+  height: 16px;
+  background: url('../images/arrowRight.png');
+  margin-left: 2px;
+}
+body[id="helios"] {
+  font-size: 11px;
+  font-family: "Lucida Grande", "Segoe UI", helvetica, arial, sans-serif;
+  background: #eee;
 }
-#helios a {
+body[id="helios"] a {
   cursor: pointer;
 }
-#helios i {
+body[id="helios"] i {
   opacity: 1;
 }
-#helios [class^="icon-"],
-#helios [class*=" icon-"] {
+body[id="helios"] [class^="icon-"],
+body[id="helios"] [class*=" icon-"] {
   margin-top: 0;
 }
-#helios .CodeMirror {
+body[id="helios"] .CodeMirror {
   position: absolute;
-  overflow: hidden;
   height: 100%;
   width: 100%;
 }
-#helios .CodeMirror-hints {
+body[id="helios"] .CodeMirror-hints {
   border-radius: 0;
-  font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
+  font-family: "Lucida Grande", "Segoe UI", helvetica, arial, sans-serif;
   font-size: 11px;
   line-height: 1em;
   padding: 0;
   max-height: 120px;
 }
-#helios .CodeMirror-hint {
+body[id="helios"] .CodeMirror-hint {
   border-radius: 0;
   padding: 0 10px;
 }
-#helios .CodeMirror pre {
-  font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
-  line-height: 16px;
-}
-#helios .CodeMirror-gutter.stops {
-  width: 20px;
-}
-#helios .CodeMirror .CodeMirror-gutter-elt {
-  line-height: 1.5em;
-}
-#helios .CodeMirror .highlighted.CodeMirror-linebackground {
-  background-color: #ffffaa;
-}
-#helios .CodeMirror .CodeMirror-gutter-elt .stop {
-  width: 16px;
-  height: 16px;
-  background: url('../images/arrowRight.png');
-  margin-left: 2px;
-}
-#helios .state {
+body[id="helios"] .state {
   position: absolute;
   right: 15px;
   top: 10px;
   width: 16px;
   height: 16px;
 }
-#helios .state.modified {
+body[id="helios"] .state.modified {
   background: transparent url('../images/modified.png') 50% 50% no-repeat;
 }
-#helios .editor {
+body[id="helios"] .editor {
   position: absolute;
   top: 0;
   bottom: 23px;
   left: 0;
   right: 0;
 }
-#helios .buttons_bar {
+body[id="helios"] .hl_widget:focus {
+  outline: 0 none;
+}
+body[id="helios"] .buttons_bar {
   position: absolute;
   bottom: 0;
   right: 0;
@@ -96,29 +96,29 @@ html[xmlns] .clearfix {
   border-top: 1px solid #999;
   text-align: right;
 }
-#helios .buttons_bar .button {
+body[id="helios"] .buttons_bar .button {
   height: 17px;
   font-size: 12px;
   min-width: 0;
 }
-#helios .btn,
-#helios .btn-group > .btn,
-#helios .btn-group > .dropdown-menu {
+body[id="helios"] .btn,
+body[id="helios"] .btn-group > .btn,
+body[id="helios"] .btn-group > .dropdown-menu {
   padding: 2px 8px;
 }
-#helios .navbar-fixed-top {
+body[id="helios"] .navbar-fixed-top {
   font-size: 11px;
   line-height: 16px;
 }
-#helios .navbar-fixed-top a span,
-#helios .dialog .nav a span {
+body[id="helios"] .navbar-fixed-top a span,
+body[id="helios"] .dialog .nav a span {
   padding: 1px;
   padding-left: 18px;
   background-position: center left;
   background-repeat: no-repeat;
   background-position: 0px -1px;
 }
-#helios .navbar-fixed-top i.close {
+body[id="helios"] .navbar-fixed-top i.close {
   width: 14px;
   height: 16px;
   margin-left: 4px;
@@ -127,31 +127,31 @@ html[xmlns] .clearfix {
   background-position: center left;
   margin-top: 2px;
 }
-#helios .navbar-fixed-top a span.references,
-#helios .dialog .nav a span.references {
+body[id="helios"] .navbar-fixed-top a span.references,
+body[id="helios"] .dialog .nav a span.references {
   background-image: url('../images/references.png');
 }
-#helios .navbar-fixed-top a span.browser,
-#helios .dialog .nav a span.browser {
+body[id="helios"] .navbar-fixed-top a span.browser,
+body[id="helios"] .dialog .nav a span.browser {
   background-image: url('../images/browser.png');
 }
-#helios .navbar-fixed-top a span.sunit,
-#helios .dialog .nav a span.sunit {
+body[id="helios"] .navbar-fixed-top a span.sunit,
+body[id="helios"] .dialog .nav a span.sunit {
   background-image: url('../images/sunit.png');
 }
-#helios .navbar-fixed-top a span.workspace,
-#helios .dialog .nav a span.workspace {
+body[id="helios"] .navbar-fixed-top a span.workspace,
+body[id="helios"] .dialog .nav a span.workspace {
   background-image: url('../images/workspace.png');
 }
-#helios .navbar-fixed-top a span.debugger,
-#helios .dialog .nav a span.debugger {
+body[id="helios"] .navbar-fixed-top a span.debugger,
+body[id="helios"] .dialog .nav a span.debugger {
   background-image: url('../images/debugger.png');
 }
-#helios .navbar-fixed-top a span.inspector,
-#helios .dialog .nav a span.inspector {
+body[id="helios"] .navbar-fixed-top a span.inspector,
+body[id="helios"] .dialog .nav a span.inspector {
   background-image: url('../images/inspector.png');
 }
-#helios .navbar-fixed-top .navbar-inner {
+body[id="helios"] .navbar-fixed-top .navbar-inner {
   min-height: 20px;
   background-color: #dbdbdb;
   border-bottom: 1px solid #666;
@@ -161,22 +161,22 @@ html[xmlns] .clearfix {
   background-image: -owebkit-linear-gradient(top, #dfdfdf, #d0d0d0);
   box-shadow: 0 0 0;
 }
-#helios .navbar .nav > li {
+body[id="helios"] .navbar .nav > li {
   line-height: 16px;
 }
-#helios .navbar .nav > li > a {
+body[id="helios"] .navbar .nav > li > a {
   line-height: 22px;
   padding: 0px 8px;
   font-size: 11px;
   color: #444;
   text-shadow: 0 1px 0 #ddd;
 }
-#helios .nav > li > a:hover {
+body[id="helios"] .nav > li > a:hover {
   background: transparent;
 }
-#helios .navbar .nav > .active > a,
-#helios .navbar .nav > .active > a:hover,
-#helios .navbar .nav > .active > a:focus {
+body[id="helios"] .navbar .nav > .active > a,
+body[id="helios"] .navbar .nav > .active > a:hover,
+body[id="helios"] .navbar .nav > .active > a:focus {
   background-color: #bababa;
   background-image: linear-gradient(left, #777777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777777 0%, #bababa 2px, transparent 2px);
   background-image: -webkit-linear-gradient(left, #777777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777777 0%, #bababa 2px, transparent 2px);
@@ -185,16 +185,16 @@ html[xmlns] .clearfix {
   text-shadow: #ddd 0px 1px 0px;
   color: #222;
 }
-#helios .navbar-fixed-top i {
+body[id="helios"] .navbar-fixed-top i {
   opacity: 0.4;
   margin-right: 5px;
   height: 12px;
   margin-top: 0;
 }
-#helios .navbar-fixed-top .active i {
+body[id="helios"] .navbar-fixed-top .active i {
   opacity: 0.6;
 }
-#helios .nav-pills.nav-stacked > li > a {
+body[id="helios"] .nav-pills.nav-stacked > li > a {
   border-radius: 0;
   -webkit-border-radius: 0;
   -moz-border-radius: 0;
@@ -204,56 +204,56 @@ html[xmlns] .clearfix {
   color: #111;
   white-space: nowrap;
 }
-#helios [class^="icon-"],
-#helios [class*=" icon-"] {
+body[id="helios"] [class^="icon-"],
+body[id="helios"] [class*=" icon-"] {
   margin-right: 2px;
 }
-#helios .dropdown-menu {
+body[id="helios"] .dropdown-menu {
   border-radius: 0;
   padding: 0;
   margin: 3px;
 }
-#helios .nav-pills > .active > a {
+body[id="helios"] .nav-pills > .active > a {
   background-color: #ddd;
   color: #fff;
   text-shadow: 0 0 0;
 }
-#helios .focused .nav-pills {
+body[id="helios"] .focused .nav-pills {
   background-color: #f3f7fb;
 }
-#helios .focused .nav-pills > .active > a,
-#helios .nav-pills > .active > a:hover,
-#helios .dropdown-menu li > a:hover,
-#helios .dropdown-menu li > a:focus,
-#helios .dropdown-submenu:hover > a,
-#helios .dropdown-menu .active > a,
-#helios .dropdown-menu .active > a:hover,
-#helios .CodeMirror-hint-active {
+body[id="helios"] .focused .nav-pills > .active > a,
+body[id="helios"] .nav-pills > .active > a:hover,
+body[id="helios"] .dropdown-menu li > a:hover,
+body[id="helios"] .dropdown-menu li > a:focus,
+body[id="helios"] .dropdown-submenu:hover > a,
+body[id="helios"] .dropdown-menu .active > a,
+body[id="helios"] .dropdown-menu .active > a:hover,
+body[id="helios"] .CodeMirror-hint-active {
   background: rgba(95, 159, 228, 0.62);
   color: #fff;
   text-shadow: 0 0 0;
 }
-#helios .tool_container {
+body[id="helios"] .tool_container {
   position: absolute;
   top: 23px;
   bottom: 0;
   left: 0;
   right: 0;
 }
-#helios .transcript textarea {
+body[id="helios"] .transcript textarea {
   width: 100%;
   height: 100%;
   margin: 0;
   padding: 0;
   border: 0;
 }
-#helios .tool_container .panes {
+body[id="helios"] .tool_container .panes {
   position: relative;
   height: 100%;
   width: 100%;
   overflow: hidden;
 }
-#helios .tool_container .panes .pane {
+body[id="helios"] .tool_container .panes .pane {
   position: absolute;
   overflow: auto;
   top: 0;
@@ -262,44 +262,44 @@ html[xmlns] .clearfix {
   bottom: 0;
   background: #fefefe;
 }
-#helios .tool_container .multi_pane {
+body[id="helios"] .tool_container .multi_pane {
   position: relative;
   height: 100%;
   width: auto;
   overflow-x: auto;
 }
-#helios .tool_container .multi_pane .pane {
+body[id="helios"] .tool_container .multi_pane .pane {
   height: 100%;
   max-width: 300px;
   border-right: 1px solid #888;
 }
-#helios .tool_container .panes .pane > div {
+body[id="helios"] .tool_container .panes .pane > div {
   height: 100%;
   position: relative;
 }
-#helios .tool_container .panes.horizontal > .pane {
+body[id="helios"] .tool_container .panes.horizontal > .pane {
   min-height: 50px;
 }
-#helios .tool_container .panes.horizontal > .pane {
+body[id="helios"] .tool_container .panes.horizontal > .pane {
   top: 50%;
 }
-#helios .tool_container .panes.horizontal > .pane:first-child {
+body[id="helios"] .tool_container .panes.horizontal > .pane:first-child {
   top: 0;
   bottom: 50%;
 }
-#helios .tool_container .panes.vertical > .pane {
+body[id="helios"] .tool_container .panes.vertical > .pane {
   left: 50%;
 }
-#helios .tool_container .panes.vertical > .pane:first-child {
+body[id="helios"] .tool_container .panes.vertical > .pane:first-child {
   left: 0;
   right: 50%;
 }
-#helios .tool_container .splitter {
+body[id="helios"] .tool_container .splitter {
   position: absolute;
   border-width: 0;
   z-index: 10;
 }
-#helios .tool_container .splitter.vertical {
+body[id="helios"] .tool_container .splitter.vertical {
   width: 5px;
   left: 50%;
   margin-left: -1px;
@@ -308,7 +308,7 @@ html[xmlns] .clearfix {
   float: left;
   cursor: ew-resize;
 }
-#helios .tool_container .splitter.horizontal {
+body[id="helios"] .tool_container .splitter.horizontal {
   top: 50%;
   height: 5px;
   margin-top: -1px;
@@ -316,7 +316,7 @@ html[xmlns] .clearfix {
   border-top: 1px solid #888;
   cursor: ns-resize;
 }
-#helios .tool_container .panes .pane .nav-pills {
+body[id="helios"] .tool_container .panes .pane .nav-pills {
   position: absolute;
   overflow-y: auto;
   top: 17px;
@@ -324,7 +324,7 @@ html[xmlns] .clearfix {
   width: 100%;
   margin: 0;
 }
-#helios .tool_container .pane .nav-pills i {
+body[id="helios"] .tool_container .pane .nav-pills i {
   display: inline-block;
   width: 16px;
   height: 16px;
@@ -334,58 +334,58 @@ html[xmlns] .clearfix {
   line-height: 14px;
   vertical-align: text-top;
 }
-#helios .tool_container .pane .nav-pills i.announcement {
+body[id="helios"] .tool_container .pane .nav-pills i.announcement {
   background-image: url('../images/announcement.png');
 }
-#helios .tool_container .pane .nav-pills i.class {
+body[id="helios"] .tool_container .pane .nav-pills i.class {
   background-image: url('../images/class.png');
 }
-#helios .tool_container .pane .nav-pills i.collection {
+body[id="helios"] .tool_container .pane .nav-pills i.collection {
   background-image: url('../images/collection.png');
 }
-#helios .tool_container .pane .nav-pills i.test {
+body[id="helios"] .tool_container .pane .nav-pills i.test {
   background-image: url('../images/test.png');
 }
-#helios .tool_container .pane .nav-pills i.exception {
+body[id="helios"] .tool_container .pane .nav-pills i.exception {
   background-image: url('../images/exception.png');
 }
-#helios .tool_container .pane .nav-pills i.widget {
+body[id="helios"] .tool_container .pane .nav-pills i.widget {
   background-image: url('../images/widget.png');
 }
-#helios .tool_container .pane .nav-pills i.magnitude {
+body[id="helios"] .tool_container .pane .nav-pills i.magnitude {
   background-image: url('../images/magnitude.png');
 }
-#helios .tool_container .pane .nav-pills i.package {
+body[id="helios"] .tool_container .pane .nav-pills i.package {
   background-image: url('../images/package.png');
 }
-#helios .tool_container .pane .nav-pills i.private {
+body[id="helios"] .tool_container .pane .nav-pills i.private {
   background-image: url('../images/private.png');
 }
-#helios .tool_container .pane .nav-pills i.extension {
+body[id="helios"] .tool_container .pane .nav-pills i.extension {
   background-image: url('../images/extension.png');
 }
-#helios .tool_container .pane .nav-pills i.initialization {
+body[id="helios"] .tool_container .pane .nav-pills i.initialization {
   background-image: url('../images/initialization.png');
 }
-#helios .tool_container .pane .nav-pills i.package {
+body[id="helios"] .tool_container .pane .nav-pills i.package {
   background-image: url('../images/package.png');
 }
-#helios .tool_container .pane .nav-pills i.override {
+body[id="helios"] .tool_container .pane .nav-pills i.override {
   background-image: url('../images/override.png ');
 }
-#helios .tool_container .pane .nav-pills i.overridden {
+body[id="helios"] .tool_container .pane .nav-pills i.overridden {
   background-image: url('../images/overridden.png');
 }
-#helios .tool_container .pane .nav-pills i.override-overridden {
+body[id="helios"] .tool_container .pane .nav-pills i.override-overridden {
   background-image: url('../images/override-overridden.png');
 }
-#helios .tool_container .pane .nav-pills i.warning {
+body[id="helios"] .tool_container .pane .nav-pills i.warning {
   background-image: url('../images/warning.gif');
 }
-#helios .tool_container .pane .nav-pills i.uncommented {
+body[id="helios"] .tool_container .pane .nav-pills i.uncommented {
   background-image: url('../images/uncommented.png');
 }
-#helios .tool_container .list-label {
+body[id="helios"] .tool_container .list-label {
   font-size: 11px;
   border-radius: 0;
   border-bottom: 1px solid #999;
@@ -403,32 +403,32 @@ html[xmlns] .clearfix {
   height: 15px;
   text-shadow: 0 1px 0 #eee;
 }
-#helios .tool_container .list-label .btn-group.cog {
+body[id="helios"] .tool_container .list-label .btn-group.cog {
   position: absolute;
   top: 0;
   right: 0;
   padding: 0;
   margin: 0;
 }
-#helios .tool_container .list-label .btn-group.open .dropdown-toggle {
+body[id="helios"] .tool_container .list-label .btn-group.open .dropdown-toggle {
   box-shadow: 0 0 0;
   border: 0;
 }
-#helios .tool_container .list-label .btn-group > .dropdown-menu {
+body[id="helios"] .tool_container .list-label .btn-group > .dropdown-menu {
   padding: 0;
   font-size: 11px;
 }
-#helios .tool_container .list-label .btn-group.cog i {
+body[id="helios"] .tool_container .list-label .btn-group.cog i {
   margin-top: 1px;
 }
-#helios .tool_container .list-label .cog .btn.dropdown-toggle {
+body[id="helios"] .tool_container .list-label .cog .btn.dropdown-toggle {
   padding: 0;
   margin: 0;
   line-height: 12px;
   border: 0;
   background: transparent;
 }
-#helios .tool_container .panes .pane .pane_actions {
+body[id="helios"] .tool_container .panes .pane .pane_actions {
   position: absolute;
   overflow: hidden;
   width: 100%;
@@ -437,8 +437,8 @@ html[xmlns] .clearfix {
   padding: 0;
   margin: 0;
 }
-#helios .tool_container .pane_actions,
-#helios .tool_container .buttons_bar {
+body[id="helios"] .tool_container .pane_actions,
+body[id="helios"] .tool_container .buttons_bar {
   background: #dadada;
   border-top: 1px solid #666;
   background-image: -webkit-linear-gradient(top, #dadada, #bdbdbd);
@@ -446,17 +446,17 @@ html[xmlns] .clearfix {
   background-image: -o-linear-gradient(top, #dadada, #bdbdbd);
   background-image: linear-gradient(top, #dadada, #bdbdbd);
 }
-#helios .tool_container .panes .pane .pane_actions .info {
+body[id="helios"] .tool_container .panes .pane .pane_actions .info {
   padding: 10px 5px 5px;
   font-weight: bold;
   color: #666;
   line-height: 20px;
 }
-#helios .tool_container .panes .pane .pane_actions .btn-group {
+body[id="helios"] .tool_container .panes .pane .pane_actions .btn-group {
   display: inline;
   margin-left: 5px;
 }
-#helios .tool_container .panes .pane .pane_actions label {
+body[id="helios"] .tool_container .panes .pane .pane_actions label {
   display: inline-block;
   padding-left: 30px;
   font-size: 11px;
@@ -465,13 +465,13 @@ html[xmlns] .clearfix {
   text-shadow: #ddd 0px 1px 0px;
   color: #222;
 }
-#helios .tool_container .panes .pane .pane_actions label input {
+body[id="helios"] .tool_container .panes .pane .pane_actions label input {
   float: none;
   vertical-align: top;
   margin-top: 2px;
   margin-right: 5px;
 }
-#helios .tool_container .panes .pane .pane_actions .btn {
+body[id="helios"] .tool_container .panes .pane .pane_actions .btn {
   background: transparent;
   border: 0;
   font-size: 11px;
@@ -482,15 +482,14 @@ html[xmlns] .clearfix {
   box-shadow: 0 0 0;
   vertical-align: top;
   /* min-width: 50px; */
-
 }
-#helios .tool_container .panes .pane .pane_actions .btn:hover {
+body[id="helios"] .tool_container .panes .pane .pane_actions .btn:hover {
   background-color: #bbb;
 }
-#helios .tool_container .panes .pane .pane_actions .btn-group .btn:hover {
+body[id="helios"] .tool_container .panes .pane .pane_actions .btn-group .btn:hover {
   background-color: transparent;
 }
-#helios .tool_container .panes .pane .pane_actions .btn-group .btn.active {
+body[id="helios"] .tool_container .panes .pane .pane_actions .btn-group .btn.active {
   text-shadow: #ddd 0px 1px 0px;
   color: #222;
   background: #bbb;
@@ -499,64 +498,81 @@ html[xmlns] .clearfix {
   background-image: -moz-linear-gradient(left, #777777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777777 0%, #bababa 2px, transparent 2px);
   background-image: -o-linear-gradient(left, #777777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777777 0%, #bababa 2px, transparent 2px);
 }
-#helios .tool_container .panes .pane .class_side .nav-pills {
+body[id="helios"] .tool_container .panes .pane .class_side .nav-pills {
   font-weight: bold;
   background: #ffffdd;
 }
-#helios .key_helper {
-  z-index: 20;
+body[id="helios"] .key_helper {
+  z-index: 2001;
   position: fixed;
-  bottom: 0px;
-  background: #fff;
-  background-image: linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-  background-image: -moz-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-  background-image: -o-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-  background-image: -webkit-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-  width: 100%;
-  border-top: 1px solid #aaa;
+  top: 120px;
+  left: 50%;
+  width: 400px;
+  max-height: 300px;
+  margin-left: -200px;
+  background: white;
+  box-shadow: 0 0 6px #aaa;
+  border: 1px solid #aaa;
   font-size: 11px;
-  height: 22px;
+  transition: all .5s;
+  -webkit-transition: all .5s;
+  -moz-transition: all .5s;
+  -o-transition: all .5s;
+  -ms-transition: all .5s;
+}
+body[id="helios"] .key_helper .command {
+  padding: 0;
+  display: inline-block;
+  width: 50%;
 }
-#helios .key_helper .command {
-  padding: 0 2px;
+body[id="helios"] .key_helper .command strong {
+  display: inline-block;
+  min-width: 1.4em;
+  text-align: left;
 }
-#helios .key_helper #binding-helper-main {
-  display: inline;
+body[id="helios"] .key_helper #binding-helper-main {
+  display: block;
+  padding: 5px;
 }
-#helios .key_helper .label {
+body[id="helios"] .key_helper .label {
   padding: 1px 4px;
   font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
   background: transparent;
-  color: #08C;
+  color: #0E4561;
   text-shadow: none;
   border: 0 none;
 }
-#helios .key_helper .action {
-  padding: 0 5px;
-  color: #666;
+body[id="helios"] .key_helper .action {
+  padding: 0 0.5em 0 5px;
+  color: inherit;
+  font-weight: bold;
 }
-#helios .key_helper .selected {
-  background-image: linear-gradient(top, #cccccc, #aaaaaa);
-  background-image: -moz-linear-gradient(top, #cccccc, #aaaaaa);
-  background-image: -o-linear-gradient(top, #cccccc, #aaaaaa);
-  background-image: -webkit-linear-gradient(top, #cccccc, #aaaaaa);
-  height: 30px;
+body[id="helios"] .key_helper .selected {
+  background-image: linear-gradient(top, #cccccc, #bbbbbb);
+  background-image: -moz-linear-gradient(top, #cccccc, #bbbbbb);
+  background-image: -o-linear-gradient(top, #cccccc, #bbbbbb);
+  background-image: -webkit-linear-gradient(top, #cccccc, #bbbbbb);
+  height: 28px;
   padding: 0 8px;
-  color: #333;
   font-weight: bold;
+  font-size: 18px;
+  line-height: 28px;
   text-shadow: 0 1px 0 #fff;
-  display: inline-block;
-  border-right: 1px solid #aaa;
+  display: block;
+  border-bottom: 1px solid #aaa;
 }
-#helios .key_helper .close {
+body[id="helios"] .key_helper .close {
   font-size: 14px;
-  line-height: 26px;
+  line-height: 28px;
   opacity: 0.6;
+  position: absolute;
+  top: 0;
+  right: 4px;
 }
-#helios .key_helper .close:hover {
+body[id="helios"] .key_helper .close:hover {
   opacity: 0.8;
 }
-#helios .key_helper input {
+body[id="helios"] .key_helper input {
   outline: none;
   font-size: 11px;
   padding: 2px 8px;
@@ -567,17 +583,12 @@ html[xmlns] .clearfix {
   margin: 2px 4px;
   line-height: 1em;
 }
-#helios .key_helper .error .help-inline,
-#helios .key_helper .error input {
+body[id="helios"] .key_helper .error .help-inline,
+body[id="helios"] .key_helper .error input {
   color: #B91010;
   font-weight: bold;
 }
-#helios .key_helper .typeahead.dropdown-menu {
-  position: fixed !important;
-  top: auto !important;
-  bottom: 30px !important;
-}
-#helios .key_helper #cog-helper {
+body[id="helios"] .key_helper #cog-helper {
   position: fixed;
   bottom: 2px;
   right: 2px;
@@ -589,10 +600,10 @@ html[xmlns] .clearfix {
   -o-transition: all .5s;
   -ms-transition: all .5s;
 }
-#helios .key_helper #cog-helper:hover {
+body[id="helios"] .key_helper #cog-helper:hover {
   opacity: 1;
 }
-#helios #helper {
+body[id="helios"] #helper {
   z-index: 300;
   top: 50%;
   position: absolute;
@@ -609,17 +620,20 @@ html[xmlns] .clearfix {
   background: rgba(0, 0, 0, 0.6);
   border-radius: 40px;
 }
-#helios #overlay {
+body[id="helios"] #overlay {
   z-index: 2000;
-  background: transparent;
+  background: rgba(112, 66, 20, 0.1);
   position: fixed;
   top: 0;
   left: 0;
   right: 0;
   bottom: 0;
 }
-#helios .confirmation,
-#helios .dialog {
+body[id="helios"] #overlay.light {
+  background: rgba(50, 50, 50, 0.1);
+}
+body[id="helios"] .confirmation,
+body[id="helios"] .dialog {
   z-index: 2001;
   background: rgba(243, 243, 243, 0.9);
   background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 5px, transparent 6px);
@@ -638,71 +652,67 @@ html[xmlns] .clearfix {
   -moz-transition: top .5s;
   -o-transition: top .5s;
 }
-#helios .confirmation .hl_widget:focus,
-#helios .dialog .hl_widget:focus {
-  outline: 0 none;
-}
-#helios .confirmation .hl_widget .form-actions,
-#helios .dialog .hl_widget .form-actions {
+body[id="helios"] .confirmation .hl_widget .form-actions,
+body[id="helios"] .dialog .hl_widget .form-actions {
   padding: 0;
   border: 0;
 }
-#helios .confirmation .nav,
-#helios .dialog .nav {
+body[id="helios"] .confirmation .nav,
+body[id="helios"] .dialog .nav {
   border: 1px solid #999;
 }
-#helios .confirmation .nav span,
-#helios .dialog .nav span {
+body[id="helios"] .confirmation .nav span,
+body[id="helios"] .dialog .nav span {
   font-size: 11px;
   font-weight: normal;
 }
-#helios .confirmation .title,
-#helios .dialog .title {
+body[id="helios"] .confirmation .title,
+body[id="helios"] .dialog .title {
   font-size: 16px;
   margin-bottom: 15px;
 }
-#helios .confirmation .large,
-#helios .dialog .large {
+body[id="helios"] .confirmation.large,
+body[id="helios"] .dialog.large {
   width: 400px;
   margin-left: -220px;
 }
-#helios .confirmation .large textarea,
-#helios .dialog .large textarea {
+body[id="helios"] .confirmation.large textarea,
+body[id="helios"] .dialog.large textarea {
   width: 385px;
   height: 200px;
 }
-#helios .confirmation textarea,
-#helios .dialog textarea {
+body[id="helios"] .confirmation textarea,
+body[id="helios"] .dialog textarea {
   display: block;
   width: 235px;
 }
-#helios .confirmation .progress,
-#helios .dialog .progress {
+body[id="helios"] .confirmation .progress,
+body[id="helios"] .dialog .progress {
   height: 5px;
 }
-#helios .confirmation .progress .bar,
-#helios .dialog .progress .bar {
+body[id="helios"] .confirmation .progress .bar,
+body[id="helios"] .dialog .progress .bar {
   background-color: #e9eaf5;
   background-image: -webkit-linear-gradient(top, #b1bdd5, #8999b8);
   background-image: -moz-linear-gradient(top, #b1bdd5, #8999b8);
   background-image: -o-linear-gradient(top, #b1bdd5, #8999b8);
   background-image: linear-gradient(top, #b1bdd5, #8999b8);
 }
-#helios .confirmation span,
-#helios .dialog span {
+body[id="helios"] .confirmation span,
+body[id="helios"] .dialog span {
   font-size: 13px;
   font-weight: bold;
 }
-#helios .confirmation .buttons,
-#helios .dialog .buttons {
+body[id="helios"] .confirmation .buttons,
+body[id="helios"] .dialog .buttons {
   text-align: right;
   margin-top: 20px;
 }
-#helios .confirmation.active,
-#helios .dialog.active {
+body[id="helios"] .confirmation.active,
+body[id="helios"] .dialog.active {
   top: 0;
 }
-#helios .button {
+body[id="helios"] .button {
   border-radius: 3px !important;
   background: #ccc;
   border: 1px solid #9B9B9B;
@@ -716,7 +726,7 @@ html[xmlns] .clearfix {
   background: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.09) 0%, rgba(0, 0, 0, 0.02) 50%, rgba(0, 0, 0, 0.04) 50.5%, rgba(0, 0, 0, 0.04) 100%) #ffffff;
   font: 13px "Lucida Grande", Lucida, Verdana, sans-serif;
 }
-#helios .button.default {
+body[id="helios"] .button.default {
   border-top: 1px solid #535273;
   border: 1px solid #4F4D67;
   border-bottom: 1px solid #4B4B58;
@@ -726,63 +736,67 @@ html[xmlns] .clearfix {
   -webkit-box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
   box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
 }
-#helios .button:hover {
+body[id="helios"] .button:hover {
   cursor: pointer;
   border: 1px solid rgba(0, 0, 0, 0.6);
 }
-#helios .button:active {
+body[id="helios"] .button:active {
   -webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
   -moz-box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
   box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.5);
 }
-#helios .button:focus {
+body[id="helios"] .button:focus {
   outline: 0;
+  border-color: #08C;
+  box-shadow: 0 0 5px #08C;
 }
-#helios .doc {
+body[id="helios"] .doc {
   background: white;
 }
-#helios .doc code .doc pre {
-  font-size: 11px;
+body[id="helios"] .doc code .doc pre,
+body[id="helios"] .doc p,
+body[id="helios"] .doc div {
+  font-size: 13px;
 }
-#helios .doc code {
+body[id="helios"] .doc code {
   padding: 1px 4px;
 }
-#helios .doc .head {
+body[id="helios"] .doc .head {
   background: #08C;
   padding: 10px;
   font-size: 22px;
   color: white;
 }
-#helios .doc .button {
+body[id="helios"] .doc .button {
   float: right;
 }
-#helios .doc .markdown,
-#helios .doc .inheritance {
+body[id="helios"] .doc .markdown,
+body[id="helios"] .doc .inheritance {
   padding: 10px;
 }
-#helios .doc h1 {
+body[id="helios"] .doc h1 {
   font-size: 22px;
   margin: 0 10px;
   border-bottom: 1px solid #666;
 }
-#helios .doc h2 {
+body[id="helios"] .doc h2 {
   font-size: 16px;
 }
-#helios .transcript_container .list-label {
+body[id="helios"] .transcript_container .list-label {
   height: 16px;
   position: absolute;
   top: 0;
   right: 0;
   left: 0;
 }
-#helios .transcript {
+body[id="helios"] .transcript {
   position: absolute;
   top: 17px;
   bottom: 0;
   left: 0;
   right: 0;
 }
-#helios .transcript textarea {
+body[id="helios"] .transcript textarea {
   width: 100%;
   height: 100%;
   margin: 0;

+ 841 - 828
css/helios.less

@@ -1,908 +1,921 @@
-body {
-    font-size: 11px;
-    font-family: "Lucida Grande", helvetica, arial, sans;
-    background: #eee;
-}
-
 .clearfix:after {
-    content: ".";
-    display: block;
-    clear: both;
-    visibility: hidden;
-    line-height: 0;
-    height: 0;
+	content: ".";
+	display: block;
+	clear: both;
+	visibility: hidden;
+	line-height: 0;
+	height: 0;
 }
 
 .clearfix {
-    display: inline-block;
+	display: inline-block;
 }
 
 html[xmlns] .clearfix {
-    display: block;
+	display: block;
 }
 
 * html .clearfix {
-    height: 1%;
+	height: 1%;
 }
 
-#helios {
-
-    a {
-	cursor: pointer;
-    }
+.cm-s-helios {
+	&.CodeMirror {
+		font-family: Menlo, Monaco, Consolas, Inconsolata, "Lucida Console", Courier, monospace;
+		line-height: 16px;
+		font-size: 13px;
+	}
 
-    i {
-	opacity: 1;
-    }
+	.CodeMirror-gutter.stops {
+		width: 20px;
+	}
 
-    [class^="icon-"], [class*=" icon-"] {
-	margin-top: 0;
-    }
+	.highlighted.CodeMirror-linebackground {
+		background-color: #ffffaa;
+	}
 
-    .CodeMirror {
-	position: absolute;
-	overflow: hidden;
-	height: 100%;
-	width: 100%;
-    }
+	.CodeMirror-gutter-elt .stop {
+		width: 16px;
+		height: 16px;
+		background: url('../images/arrowRight.png');
+		margin-left: 2px;
+	}
+}
 
-    .CodeMirror-hints {
-	border-radius: 0;
-	font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
+body[id="helios"] {
 	font-size: 11px;
-	line-height: 1em;
-	padding: 0;
-	max-height: 120px;
-    }
-
-    .CodeMirror-hint {
-	border-radius: 0;
-	padding: 0 10px;
-    }
-
-    .CodeMirror pre {
-	font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
-	line-height: 16px;
-    }
-
-    .CodeMirror-gutter.stops {
-	width: 20px;
-    }
-
-    .CodeMirror .CodeMirror-gutter-elt {
-	line-height: 1.5em;
-    }
-
-    .CodeMirror .highlighted.CodeMirror-linebackground {
-	background-color: #ffffaa;
-    }
-
-    .CodeMirror .CodeMirror-gutter-elt .stop {
-	width: 16px;
-	height: 16px;
-	background: url('../images/arrowRight.png');
-	margin-left: 2px;
-    }
-
-    .state {
-	position: absolute;
-	right: 15px;
-	top: 10px;
-	width: 16px;
-	height: 16px;
-    }
-
-    .state.modified {
-	background: transparent url('../images/modified.png') 50% 50% no-repeat;
-    }
-
-    .editor {
-	position: absolute;
-	top: 0;
-	bottom: 23px;
-	left: 0;
-	right: 0;
-    }
-
-    .buttons_bar {
-	position: absolute;
-	bottom: 0;
-	right: 0;
-	left: 0;
-	z-index: 2;
-	padding: 0px 25px;
-	height: 21px;
-	line-height: 18px;
-	border-top: 1px solid #999;
-	text-align: right;
+	font-family: "Lucida Grande", "Segoe UI", helvetica, arial, sans-serif;
+	background: #eee;
 
-	.button {
-	    height: 17px;
-	    font-size: 12px;
-	    min-width: 0;
+	a {
+		cursor: pointer;
+	}
+
+	i {
+		opacity: 1;
 	}
-    }
 
-    .btn, .btn-group > .btn, .btn-group > .dropdown-menu {
-	padding: 2px 8px;
-    }
+	[class^="icon-"], [class*=" icon-"] {
+		margin-top: 0;
+	}
 
-    .navbar-fixed-top {
-	font-size: 11px;
-	line-height: 16px;
-    }
+	.CodeMirror {
+		position: absolute;
+		height: 100%;
+		width: 100%;
+	}
+
+	.CodeMirror-hints {
+		border-radius: 0;
+		font-family: "Lucida Grande", "Segoe UI", helvetica, arial, sans-serif;
+		font-size: 11px;
+		line-height: 1em;
+		padding: 0;
+		max-height: 120px;
+	}
+
+	.CodeMirror-hint {
+		border-radius: 0;
+		padding: 0 10px;
+	}
+
+	.state {
+		position: absolute;
+		right: 15px;
+		top: 10px;
+		width: 16px;
+		height: 16px;
+	}
 
-    .navbar-fixed-top a span,
-    .dialog .nav a span {
-	padding: 1px;
-	padding-left: 18px;
-	background-position: center left;
-	background-repeat: no-repeat;
-	background-position: 0px -1px;
-    }
+	.state.modified {
+		background: transparent url('../images/modified.png') 50% 50% no-repeat;
+	}
 
-    .navbar-fixed-top i.close {
-	width: 14px;
-	height: 16px;
-	margin-left: 4px;
-	background-image: url('../images/close.gif');
-	margin-right: 0;
-	background-position: center left;
-	margin-top: 2px;
-    }
+	.editor {
+		position: absolute;
+		top: 0;
+		bottom: 23px;
+		left: 0;
+		right: 0;
+	}
 
-    .navbar-fixed-top a,
-    .dialog .nav a {
+	.hl_widget {
 
-	span.references {
-	    background-image: url('../images/references.png')
+		&:focus {
+			outline: 0 none;
+		}
 	}
 
-	span.browser {
-	    background-image: url('../images/browser.png')
+	.buttons_bar {
+		position: absolute;
+		bottom: 0;
+		right: 0;
+		left: 0;
+		z-index: 2;
+		padding: 0px 25px;
+		height: 21px;
+		line-height: 18px;
+		border-top: 1px solid #999;
+		text-align: right;
+
+		.button {
+			height: 17px;
+			font-size: 12px;
+			min-width: 0;
+		}
 	}
 
-	span.sunit {
-	    background-image: url('../images/sunit.png')
+	.btn, .btn-group > .btn, .btn-group > .dropdown-menu {
+		padding: 2px 8px;
 	}
 
-	span.workspace {
-	    background-image: url('../images/workspace.png')
+	.navbar-fixed-top {
+		font-size: 11px;
+		line-height: 16px;
 	}
 
-	span.debugger {
-	    background-image: url('../images/debugger.png')
+	.navbar-fixed-top a span,
+	.dialog .nav a span {
+		padding: 1px;
+		padding-left: 18px;
+		background-position: center left;
+		background-repeat: no-repeat;
+		background-position: 0px -1px;
 	}
-	span.inspector {
-	    background-image: url('../images/inspector.png')
+
+	.navbar-fixed-top i.close {
+		width: 14px;
+		height: 16px;
+		margin-left: 4px;
+		background-image: url('../images/close.gif');
+		margin-right: 0;
+		background-position: center left;
+		margin-top: 2px;
 	}
-    }
 
+	.navbar-fixed-top a,
+	.dialog .nav a {
 
-    .navbar-fixed-top .navbar-inner {
-	min-height: 20px;
-	background-color: #dbdbdb;
-	border-bottom: 1px solid #666;
-	background-image: linear-gradient(top, #dfdfdf, #d0d0d0);
-	background-image: -webkit-linear-gradient(top, #dfdfdf, #d0d0d0);
-	background-image: -moz-linear-gradient(top, #dfdfdf, #d0d0d0);
-	background-image: -owebkit-linear-gradient(top, #dfdfdf, #d0d0d0);
-	box-shadow: 0 0 0;
-    }
+		span.references {
+			background-image: url('../images/references.png')
+		}
 
+		span.browser {
+			background-image: url('../images/browser.png')
+		}
 
-    .navbar .nav > li {
-	line-height: 16px;
-    }
+		span.sunit {
+			background-image: url('../images/sunit.png')
+		}
 
+		span.workspace {
+			background-image: url('../images/workspace.png')
+		}
 
-    .navbar .nav > li > a {
-	line-height: 22px;
-	padding: 0px 8px;
-	font-size: 11px;
-	color: #444;
-	text-shadow: 0 1px 0 #ddd;
-    }
-
-    .nav > li > a:hover {
-	background: transparent;
-    }
-
-    .navbar .nav > .active > a, 
-    .navbar .nav > .active > a:hover, 
-    .navbar .nav > .active > a:focus {
-	background-color: #bababa;
-	background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	text-shadow: #ddd 0px 1px 0px; 
-	color: #222;
-    }
-
-    .navbar-fixed-top i {
-	opacity: 0.4;
-	margin-right: 5px;
-	height: 12px;
-	margin-top: 0;
-    }
-
-    .navbar-fixed-top .active i {
-	opacity: 0.6;
-    }
-
-    .nav-pills.nav-stacked > li > a {
-	border-radius: 0;
-	-webkit-border-radius: 0;
-	-moz-border-radius: 0;
-	padding: 2px 2px 1px 4px;
-	margin: 0;
-	font-size: 11px;
-	color: #111;
-	white-space: nowrap;
-    }
-
-    [class^="icon-"], [class*=" icon-"] {
-	margin-right: 2px;
-    }
-
-    .dropdown-menu {
-	border-radius: 0;
-	padding: 0;
-	margin: 3px;
-    }
-
-    .nav-pills > .active > a {
-	background-color: #ddd;
-	color: #fff;
-	text-shadow: 0 0 0;
-    }
-
-    .focused .nav-pills {
-	background-color: #f3f7fb;
-    }
-
-    .focused .nav-pills > .active > a, 
-    .nav-pills > .active > a:hover,
-    .dropdown-menu li > a:hover, 
-    .dropdown-menu li > a:focus, 
-    .dropdown-submenu:hover > a,
-    .dropdown-menu .active > a, 
-    .dropdown-menu .active > a:hover,
-    .CodeMirror-hint-active {
-	background: rgba(95, 159, 228, 0.62);
-	color: #fff;
-	text-shadow: 0 0 0;
-    }
-
-
-    .tool_container {
-	position: absolute;
-	top: 23px;
-	bottom: 0;
-	left: 0;
-	right: 0;
-    }
-
-    .transcript textarea {
-	width: 100%;
-	height: 100%;
-	margin: 0;
-	padding: 0;
-	border: 0;
-    }
-
-    .tool_container .panes {
-	position: relative;
-	height: 100%;
-	width: 100%;
-	overflow: hidden;
-    }
-
-    .tool_container .panes .pane {
-	position: absolute;
-	overflow: auto;
-	top: 0;
-	left: 0;
-	right: 0;
-	bottom: 0;
-	background: #fefefe;
-    }
-
-    .tool_container .multi_pane {
-	position: relative;
-	height: 100%;
-	width: auto;
-	overflow-x: auto;
-    }
-
-    .tool_container .multi_pane .pane {
-	height: 100%;
-	max-width: 300px;
-	border-right: 1px solid #888;
-    }
-
-    .tool_container .panes .pane > div {
-	height: 100%;
-	position: relative;
-    }
-
-    .tool_container .panes.horizontal > .pane {
-	min-height: 50px;
-    }
-
-    .tool_container .panes.horizontal > .pane {
-	top: 50%;
-    }
-
-    .tool_container .panes.horizontal > .pane:first-child {
-	top: 0;
-	bottom: 50%;
-    }
-
-    .tool_container .panes.vertical > .pane {
-	left: 50%;
-    }
-
-    .tool_container .panes.vertical > .pane:first-child {
-	left: 0;
-	right: 50%;
-    }
-
-
-    .tool_container .splitter {
-	position: absolute;
-	border-width: 0;
-	z-index: 10;
-    }
-
-    .tool_container .splitter.vertical {
-	width: 5px;
-	left: 50%;
-	margin-left: -1px;
-	border-left: 1px solid #888;
-	height: 100%;
-	float: left;
-	cursor: ew-resize;
-    }
-
-    .tool_container .splitter.horizontal {
-	top: 50%;
-	height: 5px;
-	margin-top: -1px;
-	width: 100%;
-	border-top: 1px solid #888;
-	cursor: ns-resize;
-    }
-
-
-
-    .tool_container .panes .pane .nav-pills {
-	position: absolute;
-	overflow-y: auto;
-	top: 17px;
-	bottom: 17px;
-	width: 100%;
-	margin: 0;
-    }
-
-    .tool_container .pane .nav-pills i {
-	display: inline-block;
-	width: 16px;
-	height: 16px;
-	margin-right: 4px;
-	background-image: none;
-	background-position: top left;
-	line-height: 14px;
-	vertical-align: text-top;
-    }
-
-    .tool_container .pane .nav-pills i.announcement {
-	background-image: url('../images/announcement.png');
-    }
-    .tool_container .pane .nav-pills i.class {
-	background-image: url('../images/class.png');
-    }
-    .tool_container .pane .nav-pills i.collection {
-	background-image: url('../images/collection.png');
-    }
-    .tool_container .pane .nav-pills i.test {
-	background-image: url('../images/test.png');
-    }
-    .tool_container .pane .nav-pills i.exception {
-	background-image: url('../images/exception.png');
-    }
-    .tool_container .pane .nav-pills i.widget {
-	background-image: url('../images/widget.png');
-    }
-    .tool_container .pane .nav-pills i.magnitude {
-	background-image: url('../images/magnitude.png');
-    }
-    .tool_container .pane .nav-pills i.package {
-	background-image: url('../images/package.png');
-    }
-    .tool_container .pane .nav-pills i.private {
-	background-image: url('../images/private.png');
-    }
-    .tool_container .pane .nav-pills i.extension {
-	background-image: url('../images/extension.png');
-    }
-    .tool_container .pane .nav-pills i.initialization {
-	background-image: url('../images/initialization.png');
-    }
-    .tool_container .pane .nav-pills i.package {
-	background-image: url('../images/package.png');
-    }
-    .tool_container .pane .nav-pills i.override {
-	background-image: url('../images/override.png ');
-    }
-    .tool_container .pane .nav-pills i.overridden {
-	background-image: url('../images/overridden.png');
-    }
-    .tool_container .pane .nav-pills i.override-overridden {
-	background-image: url('../images/override-overridden.png');
-    }
-    .tool_container .pane .nav-pills i.warning {
-	background-image: url('../images/warning.gif');
-    }
-    .tool_container .pane .nav-pills i.uncommented {
-	background-image: url('../images/uncommented.png');
-    }
-
-
-
-    .tool_container .list-label {
-	font-size: 11px;
-	border-radius: 0;
-	border-bottom: 1px solid #999;
-	border-top: 1px solid #eee;
-	background-color: #eee;
-	background-image: -webkit-linear-gradient(top, #eee, #ddd);
-	background-image: -moz-linear-gradient(top, #eee, #ddd);
-	background-image: -o-linear-gradient(top, #eee, #ddd);
-	background-image: linear-gradient(top, #eee, #ddd);
-	color: #444;
-	font-weight: bold;
-	text-shadow: 0 0 0;
-	padding-left: 4px;
-	line-height: 14px;
-	height: 15px;
-	text-shadow: 0 1px 0 #eee;
-    }
-
-    .tool_container .list-label .btn-group.cog {
-	position: absolute;
-	top: 0;
-	right: 0;
-	padding: 0;
-	margin: 0;
-    }
-
-    .tool_container .list-label .btn-group.open .dropdown-toggle {
-	box-shadow: 0 0 0;
-	border: 0;
-    }
-
-    .tool_container .list-label .btn-group > .dropdown-menu {
-	padding: 0;
-	font-size: 11px;
-    }
-
-    .tool_container .list-label .btn-group.cog i {
-	margin-top: 1px;
-    }
-
-    .tool_container .list-label .cog .btn.dropdown-toggle {
-	padding: 0;
-	margin: 0;
-	line-height: 12px;
-	border: 0;
-	background: transparent;
-    }
-
-
-    .tool_container .panes .pane .pane_actions {
-	position: absolute;
-	overflow: hidden;
-	width: 100%;
-	height: 16px;
-	bottom: 0;
-	padding: 0;
-	margin: 0;
-    }
-
-    .tool_container .pane_actions, .tool_container .buttons_bar {
-	background: #dadada;
-	border-top: 1px solid #666;
-	background-image: -webkit-linear-gradient(top, #dadada, #bdbdbd);
-	background-image: -moz-linear-gradient(top, #dadada, #bdbdbd);
-	background-image: -o-linear-gradient(top, #dadada, #bdbdbd);
-	background-image: linear-gradient(top, #dadada, #bdbdbd);
-    }
-
-    .tool_container .panes .pane .pane_actions .info {
-	padding: 10px 5px 5px;
-	font-weight: bold;
-	color: #666;
-	line-height: 20px;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn-group {
-	display: inline;
-	margin-left: 5px;
-    }
-
-    .tool_container .panes .pane .pane_actions label {
-	display: inline-block;
-	padding-left: 30px;
-	font-size: 11px;
-	line-height: 16px;
-	vertical-align: top;
-	text-shadow: #ddd 0px 1px 0px; 
-	color: #222;
-
-    }
-
-    .tool_container .panes .pane .pane_actions label input {
-	float: none;
-	vertical-align: top;
-	margin-top: 2px;
-	margin-right: 5px;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn {
-	background: transparent;
-	border: 0;
-	font-size: 11px;
-	line-height: 16px;
-	padding: 0 5px;
-	margin: 0;
-	border-radius: 0;
-	box-shadow: 0 0 0;
-	vertical-align: top;
-    /* min-width: 50px; */
-    }
-
-    .tool_container .panes .pane .pane_actions .btn:hover {
-	background-color: #bbb;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn-group .btn:hover {
-	background-color: transparent;
-    }
-
-    .tool_container .panes .pane .pane_actions .btn-group .btn.active {
-	text-shadow: #ddd 0px 1px 0px; 
-	color: #222;
-	background: #bbb;
-	background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-	background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
-    }
-
-    .tool_container .panes .pane .class_side .nav-pills {
-	font-weight: bold;
-	background: #ffd
-    }
-
-    .key_helper {
-	z-index: 20;
-	position: fixed;
-	bottom: 0px;
-	background: #fff;
-	background-image: linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	background-image: -moz-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	background-image: -o-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	background-image: -webkit-linear-gradient(top, #fafafa, #f0f0f0 50%, #e1e1e1 51%);
-	width: 100%;
-	border-top: 1px solid #aaa;
-	font-size: 11px;
-	height: 22px;
+		span.debugger {
+			background-image: url('../images/debugger.png')
+		}
+		span.inspector {
+			background-image: url('../images/inspector.png')
+		}
+	}
 
-	.command {
-	    padding: 0 2px;
+	.navbar-fixed-top .navbar-inner {
+		min-height: 20px;
+		background-color: #dbdbdb;
+		border-bottom: 1px solid #666;
+		background-image: linear-gradient(top, #dfdfdf, #d0d0d0);
+		background-image: -webkit-linear-gradient(top, #dfdfdf, #d0d0d0);
+		background-image: -moz-linear-gradient(top, #dfdfdf, #d0d0d0);
+		background-image: -owebkit-linear-gradient(top, #dfdfdf, #d0d0d0);
+		box-shadow: 0 0 0;
 	}
 
-	#binding-helper-main {
-	    display: inline;
+	.navbar .nav > li {
+		line-height: 16px;
 	}
 
-	.label {
-	    padding: 1px 4px;
-	    font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
-	    background: transparent;
-	    color: #08C;
-	    text-shadow: none;
-	    border: 0 none;
-	}
-
-	.action {
-	    padding: 0 5px;
-	    color: #666;
-	}
-
-	.selected {
-	    background-image: linear-gradient(top, #ccc, #aaa);
-	    background-image: -moz-linear-gradient(top, #ccc, #aaa);
-	    background-image: -o-linear-gradient(top, #ccc, #aaa);
-	    background-image: -webkit-linear-gradient(top, #ccc, #aaa);
-	    height: 30px;
-	    padding: 0 8px;
-	    color: #333;
-	    font-weight: bold;
-	    text-shadow: 0 1px 0 #fff;
-	    display: inline-block;
-	    border-right: 1px solid #aaa;
-	}
-
-	.close {
-	    font-size: 14px;
-	    line-height: 26px;
-	    opacity: 0.6;
-	}
-
-	.close:hover {
-	    opacity: 0.8;
-	}
-
-	input {
-	    outline: none;
-	    font-size: 11px;
-	    padding: 2px 8px;
-	    background: #fff;
-	    border: 1px solid #a1a1a1;
-	    border-radius: 12px;
-	    box-shadow: inset 0 0px 2px 0px #aaa;
-	    margin: 2px 4px;
-	    line-height: 1em;
-	}
-
-	.error .help-inline,
-	.error input {
-	    color: #B91010;
-	    font-weight: bold;
-	}
-
-	.typeahead.dropdown-menu {
-	    position: fixed !important;
-	    top: auto !important;
-	    bottom: 30px !important;
-	}
-
-	#cog-helper {
-	    position: fixed;
-	    bottom: 2px;
-	    right: 2px;
-	    z-index: 1000;
-	    opacity: 0.6;
-	    transition: all .5s;
-	    -webkit-transition: all .5s;
-	    -moz-transition: all .5s;
-	    -o-transition: all .5s;
-	    -ms-transition: all .5s;
-	}
-
-	#cog-helper:hover {
-	    opacity: 1;
-	}
-
-    }
-
-    #helper {
-	z-index: 300;
-	top: 50%;
-	position: absolute;
-	left: 50%;
-	margin-left: -220px;
-	margin-top: -35px;
-	width: 400px;
-	text-align: center;
-	color: #ddd;
-	font-size: 18px;
-	font-weight: bold;
-	text-shadow: 0 -1px 0 #111;
-	padding: 20px;
-	background: rgba(0,0,0, 0.6);
-	border-radius: 40px;
-    }
-
-    #overlay {
-	z-index: 2000;
-	background: transparent;
-	position: fixed;
-	top: 0;
-	left: 0;
-	right: 0;
-	bottom: 0;
-    }
-
-    .confirmation, .dialog {
-	z-index: 2001;
-	background: rgba(243,243,243,0.9);
-	background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	background-image: -moz-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	background-image: -o-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	background-image: linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
-	padding: 20px;
-	width: 250px;
-	position: fixed;
-	top: -500px;
-	left: 50%;
-	margin-left: -135px;
-	box-shadow: 0 0 6px #333;
-	transition: top .5s;
-	-webkit-transition: top .5s;
-	-moz-transition: top .5s;
-	-o-transition: top .5s;
+	.navbar .nav > li > a {
+		line-height: 22px;
+		padding: 0px 8px;
+		font-size: 11px;
+		color: #444;
+		text-shadow: 0 1px 0 #ddd;
+	}
 
-	.hl_widget {
-	
-	    &:focus {
-		outline: 0 none;
-	    }
+	.nav > li > a:hover {
+		background: transparent;
+	}
+
+	.navbar .nav > .active > a,
+	.navbar .nav > .active > a:hover,
+	.navbar .nav > .active > a:focus {
+		background-color: #bababa;
+		background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		text-shadow: #ddd 0px 1px 0px;
+		color: #222;
+	}
 
-	    .form-actions {
+	.navbar-fixed-top i {
+		opacity: 0.4;
+		margin-right: 5px;
+		height: 12px;
+		margin-top: 0;
+	}
+
+	.navbar-fixed-top .active i {
+		opacity: 0.6;
+	}
+
+	.nav-pills.nav-stacked > li > a {
+		border-radius: 0;
+		-webkit-border-radius: 0;
+		-moz-border-radius: 0;
+		padding: 2px 2px 1px 4px;
+		margin: 0;
+		font-size: 11px;
+		color: #111;
+		white-space: nowrap;
+	}
+
+	[class^="icon-"], [class*=" icon-"] {
+		margin-right: 2px;
+	}
+
+	.dropdown-menu {
+		border-radius: 0;
+		padding: 0;
+		margin: 3px;
+	}
+
+	.nav-pills > .active > a {
+		background-color: #ddd;
+		color: #fff;
+		text-shadow: 0 0 0;
+	}
+
+	.focused .nav-pills {
+		background-color: #f3f7fb;
+	}
+
+	.focused .nav-pills > .active > a,
+	.nav-pills > .active > a:hover,
+	.dropdown-menu li > a:hover,
+	.dropdown-menu li > a:focus,
+	.dropdown-submenu:hover > a,
+	.dropdown-menu .active > a,
+	.dropdown-menu .active > a:hover,
+	.CodeMirror-hint-active {
+		background: rgba(95, 159, 228, 0.62);
+		color: #fff;
+		text-shadow: 0 0 0;
+	}
+
+	.tool_container {
+		position: absolute;
+		top: 23px;
+		bottom: 0;
+		left: 0;
+		right: 0;
+	}
+
+	.transcript textarea {
+		width: 100%;
+		height: 100%;
+		margin: 0;
 		padding: 0;
 		border: 0;
-	    }
 	}
 
-	.nav {
-	    border: 1px solid #999;
+	.tool_container .panes {
+		position: relative;
+		height: 100%;
+		width: 100%;
+		overflow: hidden;
+	}
+
+	.tool_container .panes .pane {
+		position: absolute;
+		overflow: auto;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+		background: #fefefe;
+	}
+
+	.tool_container .multi_pane {
+		position: relative;
+		height: 100%;
+		width: auto;
+		overflow-x: auto;
+	}
+
+	.tool_container .multi_pane .pane {
+		height: 100%;
+		max-width: 300px;
+		border-right: 1px solid #888;
+	}
+
+	.tool_container .panes .pane > div {
+		height: 100%;
+		position: relative;
+	}
+
+	.tool_container .panes.horizontal > .pane {
+		min-height: 50px;
+	}
+
+	.tool_container .panes.horizontal > .pane {
+		top: 50%;
+	}
 
-	    span {
+	.tool_container .panes.horizontal > .pane:first-child {
+		top: 0;
+		bottom: 50%;
+	}
+
+	.tool_container .panes.vertical > .pane {
+		left: 50%;
+	}
+
+	.tool_container .panes.vertical > .pane:first-child {
+		left: 0;
+		right: 50%;
+	}
+
+	.tool_container .splitter {
+		position: absolute;
+		border-width: 0;
+		z-index: 10;
+	}
+
+	.tool_container .splitter.vertical {
+		width: 5px;
+		left: 50%;
+		margin-left: -1px;
+		border-left: 1px solid #888;
+		height: 100%;
+		float: left;
+		cursor: ew-resize;
+	}
+
+	.tool_container .splitter.horizontal {
+		top: 50%;
+		height: 5px;
+		margin-top: -1px;
+		width: 100%;
+		border-top: 1px solid #888;
+		cursor: ns-resize;
+	}
+
+	.tool_container .panes .pane .nav-pills {
+		position: absolute;
+		overflow-y: auto;
+		top: 17px;
+		bottom: 17px;
+		width: 100%;
+		margin: 0;
+	}
+
+	.tool_container .pane .nav-pills i {
+		display: inline-block;
+		width: 16px;
+		height: 16px;
+		margin-right: 4px;
+		background-image: none;
+		background-position: top left;
+		line-height: 14px;
+		vertical-align: text-top;
+	}
+
+	.tool_container .pane .nav-pills i.announcement {
+		background-image: url('../images/announcement.png');
+	}
+	.tool_container .pane .nav-pills i.class {
+		background-image: url('../images/class.png');
+	}
+	.tool_container .pane .nav-pills i.collection {
+		background-image: url('../images/collection.png');
+	}
+	.tool_container .pane .nav-pills i.test {
+		background-image: url('../images/test.png');
+	}
+	.tool_container .pane .nav-pills i.exception {
+		background-image: url('../images/exception.png');
+	}
+	.tool_container .pane .nav-pills i.widget {
+		background-image: url('../images/widget.png');
+	}
+	.tool_container .pane .nav-pills i.magnitude {
+		background-image: url('../images/magnitude.png');
+	}
+	.tool_container .pane .nav-pills i.package {
+		background-image: url('../images/package.png');
+	}
+	.tool_container .pane .nav-pills i.private {
+		background-image: url('../images/private.png');
+	}
+	.tool_container .pane .nav-pills i.extension {
+		background-image: url('../images/extension.png');
+	}
+	.tool_container .pane .nav-pills i.initialization {
+		background-image: url('../images/initialization.png');
+	}
+	.tool_container .pane .nav-pills i.package {
+		background-image: url('../images/package.png');
+	}
+	.tool_container .pane .nav-pills i.override {
+		background-image: url('../images/override.png ');
+	}
+	.tool_container .pane .nav-pills i.overridden {
+		background-image: url('../images/overridden.png');
+	}
+	.tool_container .pane .nav-pills i.override-overridden {
+		background-image: url('../images/override-overridden.png');
+	}
+	.tool_container .pane .nav-pills i.warning {
+		background-image: url('../images/warning.gif');
+	}
+	.tool_container .pane .nav-pills i.uncommented {
+		background-image: url('../images/uncommented.png');
+	}
+
+	.tool_container .list-label {
 		font-size: 11px;
-		font-weight: normal;
-	    }
+		border-radius: 0;
+		border-bottom: 1px solid #999;
+		border-top: 1px solid #eee;
+		background-color: #eee;
+		background-image: -webkit-linear-gradient(top, #eee, #ddd);
+		background-image: -moz-linear-gradient(top, #eee, #ddd);
+		background-image: -o-linear-gradient(top, #eee, #ddd);
+		background-image: linear-gradient(top, #eee, #ddd);
+		color: #444;
+		font-weight: bold;
+		text-shadow: 0 0 0;
+		padding-left: 4px;
+		line-height: 14px;
+		height: 15px;
+		text-shadow: 0 1px 0 #eee;
 	}
 
-	.title {
-	    font-size: 16px;
-	    margin-bottom: 15px;
+	.tool_container .list-label .btn-group.cog {
+		position: absolute;
+		top: 0;
+		right: 0;
+		padding: 0;
+		margin: 0;
 	}
 
-	.large {
-	    width: 400px;
-	    margin-left: -220px;
+	.tool_container .list-label .btn-group.open .dropdown-toggle {
+		box-shadow: 0 0 0;
+		border: 0;
+	}
 
-	    textarea {
-		width: 385px;
-		height: 200px;
-	    }
+	.tool_container .list-label .btn-group > .dropdown-menu {
+		padding: 0;
+		font-size: 11px;
 	}
 
-	textarea {
-	    display: block;
-	    width: 235px;
+	.tool_container .list-label .btn-group.cog i {
+		margin-top: 1px;
 	}
 
-	.progress {
-	    height: 5px;
+	.tool_container .list-label .cog .btn.dropdown-toggle {
+		padding: 0;
+		margin: 0;
+		line-height: 12px;
+		border: 0;
+		background: transparent;
+	}
 
-	    .bar {
-		background-color: #e9eaf5;
-		background-image: -webkit-linear-gradient(top, #B1BDD5, #8999b8);
-		background-image: -moz-linear-gradient(top, #B1BDD5, #8999b8);
-		background-image: -o-linear-gradient(top, #B1BDD5, #8999b8);
-		background-image: linear-gradient(top, #B1BDD5, #8999b8);
-	    }
+	.tool_container .panes .pane .pane_actions {
+		position: absolute;
+		overflow: hidden;
+		width: 100%;
+		height: 16px;
+		bottom: 0;
+		padding: 0;
+		margin: 0;
 	}
 
-	span {
-	    font-size: 13px;
-	    font-weight: bold;
+	.tool_container .pane_actions, .tool_container .buttons_bar {
+		background: #dadada;
+		border-top: 1px solid #666;
+		background-image: -webkit-linear-gradient(top, #dadada, #bdbdbd);
+		background-image: -moz-linear-gradient(top, #dadada, #bdbdbd);
+		background-image: -o-linear-gradient(top, #dadada, #bdbdbd);
+		background-image: linear-gradient(top, #dadada, #bdbdbd);
 	}
 
-	.buttons {
-	    text-align: right;
-	    margin-top: 20px;
+	.tool_container .panes .pane .pane_actions .info {
+		padding: 10px 5px 5px;
+		font-weight: bold;
+		color: #666;
+		line-height: 20px;
 	}
 
-	&.active {
-	    top: 0;
+	.tool_container .panes .pane .pane_actions .btn-group {
+		display: inline;
+		margin-left: 5px;
 	}
-    }
 
-    .button {
-	border-radius: 3px !important;
-	background: #ccc;
-	border: 1px solid #9B9B9B;
-	height: 20px;
-	border-radius: 5px;
-	min-width: 68px;
-	padding: 0 10px;
-	text-align: center;
-	margin: 0;
-	margin-left: 10px;
-	background: -webkit-linear-gradient(bottom, rgba(0,0,0,.09) 0%, rgba(0,0,0, 0.02) 50%, rgba(0,0,0,.04) 50.5%, rgba(0,0,0,.04) 100%) #fff;
-	font: 13px "Lucida Grande", Lucida, Verdana, sans-serif;
-    }
+	.tool_container .panes .pane .pane_actions label {
+		display: inline-block;
+		padding-left: 30px;
+		font-size: 11px;
+		line-height: 16px;
+		vertical-align: top;
+		text-shadow: #ddd 0px 1px 0px;
+		color: #222;
+
+	}
 
-    .button.default { 
-	border-top: 1px solid #535273;
-	border: 1px solid #4F4D67;
-	border-bottom: 1px solid #4B4B58;    
-	background: -webkit-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
-	background: -moz-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
-	-moz-box-shadow: 0 0 3px rgba(69, 113, 184, 0.8);
-	-webkit-box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
-	box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
-    }
+	.tool_container .panes .pane .pane_actions label input {
+		float: none;
+		vertical-align: top;
+		margin-top: 2px;
+		margin-right: 5px;
+	}
 
+	.tool_container .panes .pane .pane_actions .btn {
+		background: transparent;
+		border: 0;
+		font-size: 11px;
+		line-height: 16px;
+		padding: 0 5px;
+		margin: 0;
+		border-radius: 0;
+		box-shadow: 0 0 0;
+		vertical-align: top;
+		/* min-width: 50px; */
+	}
 
-    .button:hover {
-	cursor: pointer;
-	border: 1px solid rgba(0,0,0,.6);
-    }
+	.tool_container .panes .pane .pane_actions .btn:hover {
+		background-color: #bbb;
+	}
 
-    .button:active {
-	-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
-	-moz-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
-	box-shadow: inset 0 0 5px rgba(0,0,0,.5);
-    }
+	.tool_container .panes .pane .pane_actions .btn-group .btn:hover {
+		background-color: transparent;
+	}
 
-    .button:focus {
-	outline: 0;
-    }
+	.tool_container .panes .pane .pane_actions .btn-group .btn.active {
+		text-shadow: #ddd 0px 1px 0px;
+		color: #222;
+		background: #bbb;
+		background-image: linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -webkit-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -webkit-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -moz-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -moz-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+		background-image: -o-linear-gradient(left, #777 0%, #bababa 2px, transparent 2px), -o-linear-gradient(right, #777 0%, #bababa 2px, transparent 2px);
+	}
 
-    .doc {
-	background: white;
-    }
+	.tool_container .panes .pane .class_side .nav-pills {
+		font-weight: bold;
+		background: #ffd
+	}
 
-    .doc code .doc pre {
-	font-size: 11px;
-    }
-
-    .doc code {
-	padding: 1px 4px;
-    }
-    .doc .head {
-	background: #08C;
-	padding: 10px;
-	font-size: 22px;
-	color: white;
-    }
-
-    .doc .button {
-	float: right;
-    }
-    .doc .markdown,
-    .doc .inheritance {
-	padding: 10px;
-    }
-
-    .doc h1 {
-	font-size: 22px;
-	margin: 0 10px;
-	border-bottom: 1px solid #666;
-    }
-
-    .doc h2 {
-	font-size: 16px;
-    }
-
-    .transcript_container .list-label {
-	height: 16px;
-	position: absolute;
-	top: 0;
-	right: 0;
-	left: 0;
-    }
-
-    .transcript {
-	position: absolute;
-	top: 17px;
-	bottom: 0;
-	left: 0;
-	right: 0;
-    }
-
-    .transcript textarea {
-	width: 100%;
-	height: 100%;
-	margin: 0;
-	padding: 0;
-	border: 0;
-    }
+	.key_helper {
+		z-index: 2001;
+		position: fixed;
+		top: 120px;
+		left: 50%;
+		width: 400px;
+		max-height: 300px;
+		margin-left: -200px;
+		background: white;
+		box-shadow: 0 0 6px #aaa;
+		border: 1px solid #aaa;
+		font-size: 11px;
+
+		transition: all .5s;
+		-webkit-transition: all .5s;
+		-moz-transition: all .5s;
+		-o-transition: all .5s;
+		-ms-transition: all .5s;
+
+
+		.command {
+			padding: 0;
+			display: inline-block;
+			width: 50%;
+
+			strong {
+				display: inline-block;
+				min-width: 1.4em;
+				text-align: left;
+			}
+		}
+
+		#binding-helper-main {
+			display: block;
+			padding: 5px;
+		}
+
+		.label {
+			padding: 1px 4px;
+			font-family: Menlo, Monaco, "Lucida Console", Courier, monospace;
+			background: transparent;
+			color: #0E4561;
+			text-shadow: none;
+			border: 0 none;
+		}
+
+		.action {
+			padding: 0 0.5em 0 5px;
+			color: inherit;
+			font-weight: bold;
+		}
+
+		.selected {
+			background-image: linear-gradient(top, #ccc, #bbb);
+			background-image: -moz-linear-gradient(top, #ccc, #bbb);
+			background-image: -o-linear-gradient(top, #ccc, #bbb);
+			background-image: -webkit-linear-gradient(top, #ccc, #bbb);
+			height: 28px;
+			padding: 0 8px;
+			font-weight: bold;
+			font-size: 18px;
+			line-height: 28px;
+			text-shadow: 0 1px 0 #fff;
+			display: block;
+			border-bottom: 1px solid #aaa;
+		}
+
+		.close {
+			font-size: 14px;
+			line-height: 28px;
+			opacity: 0.6;
+			position: absolute;
+			top: 0;
+			right: 4px;
+		}
+
+		.close:hover {
+			opacity: 0.8;
+		}
+
+		input {
+			outline: none;
+			font-size: 11px;
+			padding: 2px 8px;
+			background: #fff;
+			border: 1px solid #a1a1a1;
+			border-radius: 12px;
+			box-shadow: inset 0 0px 2px 0px #aaa;
+			margin: 2px 4px;
+			line-height: 1em;
+		}
+
+		.error .help-inline,
+		.error input {
+			color: #B91010;
+			font-weight: bold;
+		}
+
+		// .typeahead.dropdown-menu {
+		// 	position: fixed !important;
+		// 	top: auto !important;
+		// 	bottom: 30px !important;
+		// }
+
+		#cog-helper {
+			position: fixed;
+			bottom: 2px;
+			right: 2px;
+			z-index: 1000;
+			opacity: 0.6;
+			transition: all .5s;
+			-webkit-transition: all .5s;
+			-moz-transition: all .5s;
+			-o-transition: all .5s;
+			-ms-transition: all .5s;
+		}
+
+		#cog-helper:hover {
+			opacity: 1;
+		}
+
+	}
+
+	#helper {
+		z-index: 300;
+		top: 50%;
+		position: absolute;
+		left: 50%;
+		margin-left: -220px;
+		margin-top: -35px;
+		width: 400px;
+		text-align: center;
+		color: #ddd;
+		font-size: 18px;
+		font-weight: bold;
+		text-shadow: 0 -1px 0 #111;
+		padding: 20px;
+		background: rgba(0, 0, 0, 0.6);
+		border-radius: 40px;
+	}
+
+	#overlay {
+		z-index: 2000;
+		background: rgba(112, 66, 20, 0.1);
+		position: fixed;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+
+		&.light {
+			background: rgba(50, 50, 50, 0.1);
+		}
+	}
+
+	.confirmation, .dialog {
+		z-index: 2001;
+		background: rgba(243, 243, 243, 0.9);
+		background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 5px, transparent 6px);
+		background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 5px, transparent 6px);
+		background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 5px, transparent 6px);
+		background-image: linear-gradient(top, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0) 5px, transparent 6px);
+		padding: 20px;
+		width: 250px;
+		position: fixed;
+		top: -500px;
+		left: 50%;
+		margin-left: -135px;
+		box-shadow: 0 0 6px #333;
+		transition: top .5s;
+		-webkit-transition: top .5s;
+		-moz-transition: top .5s;
+		-o-transition: top .5s;
+
+		.hl_widget {
+
+			.form-actions {
+				padding: 0;
+				border: 0;
+			}
+		}
+
+		.nav {
+			border: 1px solid #999;
+
+			span {
+				font-size: 11px;
+				font-weight: normal;
+			}
+		}
+
+		.title {
+			font-size: 16px;
+			margin-bottom: 15px;
+		}
+
+		&.large {
+			width: 400px;
+			margin-left: -220px;
+
+			textarea {
+				width: 385px;
+				height: 200px;
+			}
+		}
+
+		textarea {
+			display: block;
+			width: 235px;
+		}
+
+		.progress {
+			height: 5px;
+
+			.bar {
+				background-color: #e9eaf5;
+				background-image: -webkit-linear-gradient(top, #B1BDD5, #8999b8);
+				background-image: -moz-linear-gradient(top, #B1BDD5, #8999b8);
+				background-image: -o-linear-gradient(top, #B1BDD5, #8999b8);
+				background-image: linear-gradient(top, #B1BDD5, #8999b8);
+			}
+		}
+
+		span {
+			font-size: 13px;
+			font-weight: bold;
+		}
+
+		.buttons {
+			text-align: right;
+			margin-top: 20px;
+		}
+
+		&.active {
+			top: 0;
+		}
+	}
+
+	.button {
+		border-radius: 3px !important;
+		background: #ccc;
+		border: 1px solid #9B9B9B;
+		height: 20px;
+		border-radius: 5px;
+		min-width: 68px;
+		padding: 0 10px;
+		text-align: center;
+		margin: 0;
+		margin-left: 10px;
+		background: -webkit-linear-gradient(bottom, rgba(0, 0, 0, .09) 0%, rgba(0, 0, 0, 0.02) 50%, rgba(0, 0, 0, .04) 50.5%, rgba(0, 0, 0, .04) 100%) #fff;
+		font: 13px "Lucida Grande", Lucida, Verdana, sans-serif;
+	}
+
+	.button.default {
+		border-top: 1px solid #535273;
+		border: 1px solid #4F4D67;
+		border-bottom: 1px solid #4B4B58;
+		background: -webkit-linear-gradient(bottom, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, .3) 50.5%, rgba(255, 255, 255, .45) 95%, rgba(255, 255, 255, .8) 100%) #b1bdd5;
+		background: -moz-linear-gradient(bottom, rgba(255, 255, 255, .5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255, 255, 255, .3) 50.5%, rgba(255, 255, 255, .45) 95%, rgba(255, 255, 255, .8) 100%) #b1bdd5;
+		-moz-box-shadow: 0 0 3px rgba(69, 113, 184, 0.8);
+		-webkit-box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
+		box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
+	}
+
+	.button:hover {
+		cursor: pointer;
+		border: 1px solid rgba(0, 0, 0, .6);
+	}
+
+	.button:active {
+		-webkit-box-shadow: inset 0 0 5px rgba(0, 0, 0, .5);
+		-moz-box-shadow: inset 0 0 5px rgba(0, 0, 0, .5);
+		box-shadow: inset 0 0 5px rgba(0, 0, 0, .5);
+	}
+
+	.button:focus {
+		outline: 0;
+		border-color: #08C;
+		box-shadow: 0 0 5px #08C;
+	}
+
+	.doc {
+		background: white;
+	}
+
+	.doc code .doc pre, .doc p, .doc div {
+		font-size: 13px;
+	}
+
+	.doc code {
+		padding: 1px 4px;
+	}
+	.doc .head {
+		background: #08C;
+		padding: 10px;
+		font-size: 22px;
+		color: white;
+	}
+
+	.doc .button {
+		float: right;
+	}
+	.doc .markdown,
+	.doc .inheritance {
+		padding: 10px;
+	}
+
+	.doc h1 {
+		font-size: 22px;
+		margin: 0 10px;
+		border-bottom: 1px solid #666;
+	}
+
+	.doc h2 {
+		font-size: 16px;
+	}
+
+	.transcript_container .list-label {
+		height: 16px;
+		position: absolute;
+		top: 0;
+		right: 0;
+		left: 0;
+	}
+
+	.transcript {
+		position: absolute;
+		top: 17px;
+		bottom: 0;
+		left: 0;
+		right: 0;
+	}
+
+	.transcript textarea {
+		width: 100%;
+		height: 100%;
+		margin: 0;
+		padding: 0;
+		border: 0;
+	}
 }

+ 17 - 7
grunt/tasks/grunt-amberc.js

@@ -2,7 +2,7 @@ module.exports = function(grunt) {
 
   var path = require('path');
   var fs = require('fs');
-  var amberc = require('../../bin/amberc.js');
+  var amberc = require('../../cli/support/amberc.js');
 
   /**
      A full example entry for a Gruntfile.js is available below.
@@ -15,11 +15,15 @@ module.exports = function(grunt) {
 
      amberc: {
        options: {
-         amber_dir: process.cwd(),     // REQUIRED
-         verbose: true                 // optional
+         amber_dir: process.cwd(),                // REQUIRED
+         library_dirs: ['dir1', '/usr/local/js'], // optional
+         verbose: true                            // optional
        },
        helloWorld: {
-         options: {                             // the 'options' object is optional
+         // this 'options' object is optional as well as all parameters inside it
+         // they can be used to override the global 'options'
+         options: {
+           library_dirs: ['dir1', '/usr/local/js'], // optional
            verbose: true
          },
          src: ['projects/HelloWorld/st/HelloWorld.st'], // REQUIRED
@@ -42,9 +46,11 @@ module.exports = function(grunt) {
 
     var options = this.options({
       amber_dir: undefined,
+      library_dirs: [],
       verbose: grunt.option('verbose') || false
     });
     this.data.verbose = options.verbose;
+    this.data.library_dirs = options.library_dirs;
 
     // mark required properties
     this.requiresConfig('amberc.options.amber_dir');
@@ -57,7 +63,7 @@ module.exports = function(grunt) {
     var compiler = new amberc.Compiler(grunt.config('amberc.options.amber_dir'));
 
     // generate the amberc configuration out of the given target properties
-    var configuration = generateCompilerConfiguration(this.data, this.filesSrc, grunt.config('amberc.options.amber_dir'));
+    var configuration = generateCompilerConfiguration(this.data, this.filesSrc);
 
     // run the compiler and call the async callback once finished
     var self = this;
@@ -68,14 +74,18 @@ module.exports = function(grunt) {
   });
 
 
-  function generateCompilerConfiguration(data, sourceFiles, amber_dir) {
-    var configuration = amberc.createDefaults(amber_dir);
+  function generateCompilerConfiguration(data, sourceFiles) {
+    var configuration = amberc.createDefaultConfiguration();
     var parameters = [];
 
     var libraries = data.libraries;
     if (undefined !== libraries) {
       configuration.load = libraries;
     }
+    var library_dirs = data.library_dirs;
+    if (undefined !== library_dirs) {
+      configuration.jsLibraryDirs = library_dirs;
+    }
     var mainClass = data.main_class;
     if (undefined !== mainClass) {
       configuration.main = mainClass;

+ 10 - 15
grunt/tasks/grunt-peg.js

@@ -1,29 +1,24 @@
 module.exports = function(grunt) {
 
-  var PEG = require('pegjs');
+	var PEG = require('pegjs');
 
-  /**
-    Full config looks like this:
-    pegjs: {
-       my_parser: {
-         options: {                       // optional
-           trackLineAndColumn: true,      // default: false
-           cache: true,                   // default: false
-           export_var: 'smalltalk.parser' // default: module.exports
-         },
-         src: 'parser.pegjs',
-         dest: 'parser.js',
-       }
+	/**
+     Full config looks like this:
+     pegjs: {
+     my_parser: {
+     options: {                       // optional
+     cache: true,                   // default: false
+     export_var: 'smalltalk.parser' // default: module.exports
      },
    */
   grunt.registerMultiTask('peg', 'Generate JavaScript parser from PEG.js grammar description', function() {
     var options = this.options({
       cache: false,
-      trackLineAndColumn: false,
+      output: 'source',
       export_var: 'module.exports'
     });
     var parser = PEG.buildParser(grunt.file.read(this.data.src), options);
-    var content = 'define("amber_vm/parser", ["./smalltalk", "./nil"], function(smalltalk, nil) {\n'+options.export_var + ' = ' + parser.toSource() + ';\n});';
+    var content = 'define("amber_vm/parser", ["./globals", "./nil"], function(globals, nil) {\n'+options.export_var + ' = ' + parser + ';\n});';
     grunt.file.write(this.data.dest, content);
   });
 };

+ 2 - 2
helios.html

@@ -20,8 +20,8 @@
                           return 'Do you want to close Amber? All uncommitted changes will be lost.';
                       };
 
-                      smalltalk.defaultAmdNamespace = "amber_core";
-                      smalltalk.initialize();
+                      smalltalk.initialize({'transport.defaultAmdNamespace': "amber_core"});
+					  smalltalk.globals.HLManager._setup();
                   }
           );
       </script>

BIN
images/package.png


+ 2 - 3
index.html

@@ -14,10 +14,9 @@
     require(
         ["amber/devel"],
         function (smalltalk) {
-            smalltalk.defaultAmdNamespace = "amber_core";
-            smalltalk.initialize();
+            smalltalk.initialize({'transport.defaultAmdNamespace': "amber_core"});
 
-            smalltalk.Browser._open()
+            smalltalk.globals.Browser._open();
         }
     );
 </script>

+ 74 - 32
js/Benchfib.js

@@ -1,58 +1,64 @@
-define("amber_core/Benchfib", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Benchfib", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Benchfib');
 smalltalk.packages["Benchfib"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('Benchfib', smalltalk.Object, [], 'Benchfib');
+smalltalk.addClass('Benchfib', globals.Object, [], 'Benchfib');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "main",
-category: 'not yet classified',
+protocol: 'not yet classified',
 fn: function (){
 var self=this;
 var result;
 return smalltalk.withContext(function($ctx1) { 
 result=(0)._tinyBenchmarks();
 _st(console)._log_("0 tinyBenchmarks => ".__comma(result));
-return self}, function($ctx1) {$ctx1.fill(self,"main",{result:result},smalltalk.Benchfib.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"main",{result:result},globals.Benchfib.klass)})},
 args: [],
 source: "main\x0a\x0a\x09| result |\x0a\x09result := 0 tinyBenchmarks.\x0a\x09console log: '0 tinyBenchmarks => ' , result",
 messageSends: ["tinyBenchmarks", "log:", ","],
 referencedClasses: []
 }),
-smalltalk.Benchfib.klass);
+globals.Benchfib.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "benchFib",
-category: '*Benchfib',
+protocol: '*Benchfib',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
+var $2,$5,$4,$3,$1;
 $2=self.__lt((2));
 if(smalltalk.assert($2)){
 $1=(1);
 } else {
-$1=_st(_st(_st(self.__minus((1)))._benchFib()).__plus(_st(self.__minus((2)))._benchFib())).__plus((1));
+$5=self.__minus((1));
+$ctx1.sendIdx["-"]=1;
+$4=_st($5)._benchFib();
+$ctx1.sendIdx["benchFib"]=1;
+$3=_st($4).__plus(_st(self.__minus((2)))._benchFib());
+$1=_st($3).__plus((1));
+$ctx1.sendIdx["+"]=1;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"benchFib",{},smalltalk.Number)})},
+}, function($ctx1) {$ctx1.fill(self,"benchFib",{},globals.Number)})},
 args: [],
 source: "benchFib\x0a\x09\x22Handy send-heavy benchmark\x22\x0a\x09\x22(result // seconds to run) = approx calls per second\x22\x0a\x09\x22\x09| r t |\x0a\x09\x09t := Time millisecondsToRun: [r := 26 benchFib].\x0a\x09\x09(r * 1000) // t\x22\x0a\x09\x22138000 on a Mac 8100/100\x22\x0a\x09^ self < 2\x0a\x09\x09ifTrue: [1]\x0a\x09\x09ifFalse: [(self-1) benchFib + (self-2) benchFib + 1]",
 messageSends: ["ifTrue:ifFalse:", "<", "+", "benchFib", "-"],
 referencedClasses: []
 }),
-smalltalk.Number);
+globals.Number);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "benchmark",
-category: '*Benchfib',
+protocol: '*Benchfib',
 fn: function (){
 var self=this;
 var size,flags,prime,k,count;
-function $Array(){return smalltalk.Array||(typeof Array=="undefined"?nil:Array)}
+function $Array(){return globals.Array||(typeof Array=="undefined"?nil:Array)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 size=(8190);
@@ -71,8 +77,10 @@ return smalltalk.withContext(function($ctx3) {
 $1=_st(flags)._at_(i);
 if(smalltalk.assert($1)){
 prime=_st(i).__plus((1));
+$ctx3.sendIdx["+"]=1;
 prime;
 k=_st(i).__plus(prime);
+$ctx3.sendIdx["+"]=2;
 k;
 _st((function(){
 return smalltalk.withContext(function($ctx4) {
@@ -81,6 +89,7 @@ return _st(k).__lt_eq(size);
 return smalltalk.withContext(function($ctx4) {
 _st(flags)._at_put_(k,false);
 k=_st(k).__plus(prime);
+$ctx4.sendIdx["+"]=3;
 return k;
 }, function($ctx4) {$ctx4.fillBlock({},$ctx3,6)})}));
 count=_st(count).__plus((1));
@@ -88,20 +97,21 @@ return count;
 };
 }, function($ctx3) {$ctx3.fillBlock({i:i},$ctx2,3)})}));
 }, function($ctx2) {$ctx2.fillBlock({iter:iter},$ctx1,1)})}));
+$ctx1.sendIdx["to:do:"]=1;
 $2=count;
 return $2;
-}, function($ctx1) {$ctx1.fill(self,"benchmark",{size:size,flags:flags,prime:prime,k:k,count:count},smalltalk.Number)})},
+}, function($ctx1) {$ctx1.fill(self,"benchmark",{size:size,flags:flags,prime:prime,k:k,count:count},globals.Number)})},
 args: [],
 source: "benchmark\x0a\x09\x22Handy bytecode-heavy benchmark\x22\x0a\x09\x22(500000 // time to run) = approx bytecodes per second\x22\x0a\x09\x225000000 // (Time millisecondsToRun: [10 benchmark]) * 1000\x22\x0a\x09\x223059000 on a Mac 8100/100\x22\x0a\x09| size flags prime k count |\x0a\x09size := 8190.\x0a\x091 to: self do:\x0a\x09\x09[:iter |\x0a\x09\x09count := 0.\x0a\x09\x09flags := Array new.\x0a\x09\x09size timesRepeat: [ flags add: true].\x0a\x09\x091 to: size do:\x0a\x09\x09\x09[:i | (flags at: i) ifTrue:\x0a\x09\x09\x09\x09[prime := i+1.\x0a\x09\x09\x09\x09k := i + prime.\x0a\x09\x09\x09\x09[k <= size] whileTrue:\x0a\x09\x09\x09\x09\x09[flags at: k put: false.\x0a\x09\x09\x09\x09\x09k := k + prime].\x0a\x09\x09\x09\x09count := count + 1]]].\x0a\x09^ count",
 messageSends: ["to:do:", "new", "timesRepeat:", "add:", "ifTrue:", "at:", "+", "whileTrue:", "<=", "at:put:"],
 referencedClasses: ["Array"]
 }),
-smalltalk.Number);
+globals.Number);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "jsbenchFib",
-category: '*Benchfib',
+protocol: '*Benchfib',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -109,18 +119,18 @@ if (this < 2) {
 return 1;
 } else {
 return (this-1)._jsbenchFib() + (this-2)._jsbenchFib() + 1;};
-return self}, function($ctx1) {$ctx1.fill(self,"jsbenchFib",{},smalltalk.Number)})},
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchFib",{},globals.Number)})},
 args: [],
 source: "jsbenchFib\x0a\x0a\x09<if (this < 2) {\x0areturn 1;\x0a} else {\x0areturn (this-1)._jsbenchFib() + (this-2)._jsbenchFib() + 1;}>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Number);
+globals.Number);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "jsbenchmark",
-category: '*Benchfib',
+protocol: '*Benchfib',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -146,24 +156,24 @@ for (var z=0;z<this;z++) {
 	}
 }
 return count;
-return self}, function($ctx1) {$ctx1.fill(self,"jsbenchmark",{},smalltalk.Number)})},
+return self}, function($ctx1) {$ctx1.fill(self,"jsbenchmark",{},globals.Number)})},
 args: [],
 source: "jsbenchmark\x0a\x0a<\x0avar size = 8190;\x0avar count;\x0afor (var z=0;z<this;z++) {\x0a\x09count = 0;\x0a\x09var flags = new Array();\x0a\x09for (var p=0; p<size; p++) {\x0a\x09flags[p] = true;\x0a\x09}\x0a\x09for (var i=1;i<=size;i++) {\x0a\x09\x09if (flags[i-1]) {\x0a\x09\x09\x09var prime = i+1;\x0a\x09\x09\x09var k = i + prime;\x0a\x09\x09\x09while (k <= size) {\x0a\x09\x09\x09\x09flags[k-1] = false;\x0a\x09\x09\x09\x09k = k + prime;\x0a\x09\x09\x09}\x0a\x09\x09\x09count = count + 1;\x0a\x09\x09}\x0a\x09}\x0a}\x0areturn count>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Number);
+globals.Number);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "jstinyBenchmarks",
-category: '*Benchfib',
+protocol: '*Benchfib',
 fn: function (){
 var self=this;
 var t1,t2,r,n1,n2;
-function $Date(){return smalltalk.Date||(typeof Date=="undefined"?nil:Date)}
+function $Date(){return globals.Date||(typeof Date=="undefined"?nil:Date)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $7,$6,$5,$4,$3,$2,$1;
 n1=(1);
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -171,13 +181,17 @@ t1=_st($Date())._millisecondsToRun_((function(){
 return smalltalk.withContext(function($ctx3) {
 return _st(n1)._jsbenchmark();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+$ctx2.sendIdx["millisecondsToRun:"]=1;
 t1;
 return _st(t1).__lt((1000));
+$ctx2.sendIdx["<"]=1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._whileTrue_((function(){
 return smalltalk.withContext(function($ctx2) {
 n1=_st(n1).__star((2));
+$ctx2.sendIdx["*"]=1;
 return n1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,3)})}));
+$ctx1.sendIdx["whileTrue:"]=1;
 n2=(28);
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -193,26 +207,38 @@ return smalltalk.withContext(function($ctx2) {
 n2=_st(n2).__plus((1));
 return n2;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,6)})}));
-$1=_st(_st(_st(_st(_st(_st(_st(n1).__star((500000))).__star((1000))).__slash(t1))._printString()).__comma(" bytecodes/sec; ")).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString())).__comma(" sends/sec");
+$7=_st(n1).__star((500000));
+$ctx1.sendIdx["*"]=3;
+$6=_st($7).__star((1000));
+$ctx1.sendIdx["*"]=2;
+$5=_st($6).__slash(t1);
+$ctx1.sendIdx["/"]=1;
+$4=_st($5)._printString();
+$ctx1.sendIdx["printString"]=1;
+$3=_st($4).__comma(" bytecodes/sec; ");
+$2=_st($3).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString());
+$ctx1.sendIdx[","]=2;
+$1=_st($2).__comma(" sends/sec");
+$ctx1.sendIdx[","]=1;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"jstinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2},smalltalk.Number)})},
+}, function($ctx1) {$ctx1.fill(self,"jstinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2},globals.Number)})},
 args: [],
 source: "jstinyBenchmarks\x0a\x09\x220 jstinyBenchmarks\x22\x0a\x0a\x09| t1 t2 r n1 n2 |\x0a\x09n1 := 1.\x0a\x09[t1 := Date millisecondsToRun: [n1 jsbenchmark].\x0a\x09t1 < 1000] whileTrue:[n1 := n1 * 2]. \x22Note: #benchmark's runtime is about O(n)\x22\x0a\x0a\x09n2 := 28.\x0a\x09[t2 := Date millisecondsToRun: [r := n2 jsbenchFib].\x0a\x09t2 < 1000] whileTrue:[n2 := n2 + 1].\x0a\x09\x22Note: #jsbenchFib's runtime is about O(k^n),\x0a\x09\x09where k is the golden number = (1 + 5 sqrt) / 2 = 1.618....\x22\x0a\x0a\x09^ ((n1 * 500000 * 1000) / t1) printString, ' bytecodes/sec; ',\x0a\x09\x09((r * 1000) / t2) printString, ' sends/sec'",
 messageSends: ["whileTrue:", "millisecondsToRun:", "jsbenchmark", "<", "*", "jsbenchFib", "+", ",", "printString", "/"],
 referencedClasses: ["Date"]
 }),
-smalltalk.Number);
+globals.Number);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "tinyBenchmarks",
-category: '*Benchfib',
+protocol: '*Benchfib',
 fn: function (){
 var self=this;
 var t1,t2,r,n1,n2;
-function $Date(){return smalltalk.Date||(typeof Date=="undefined"?nil:Date)}
+function $Date(){return globals.Date||(typeof Date=="undefined"?nil:Date)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $7,$6,$5,$4,$3,$2,$1;
 n1=(1);
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -220,13 +246,17 @@ t1=_st($Date())._millisecondsToRun_((function(){
 return smalltalk.withContext(function($ctx3) {
 return _st(n1)._benchmark();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+$ctx2.sendIdx["millisecondsToRun:"]=1;
 t1;
 return _st(t1).__lt((1000));
+$ctx2.sendIdx["<"]=1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._whileTrue_((function(){
 return smalltalk.withContext(function($ctx2) {
 n1=_st(n1).__star((2));
+$ctx2.sendIdx["*"]=1;
 return n1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,3)})}));
+$ctx1.sendIdx["whileTrue:"]=1;
 n2=(16);
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -242,14 +272,26 @@ return smalltalk.withContext(function($ctx2) {
 n2=_st(n2).__plus((1));
 return n2;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,6)})}));
-$1=_st(_st(_st(_st(_st(_st(_st(n1).__star((500000))).__star((1000))).__slash(t1))._printString()).__comma(" bytecodes/sec; ")).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString())).__comma(" sends/sec");
+$7=_st(n1).__star((500000));
+$ctx1.sendIdx["*"]=3;
+$6=_st($7).__star((1000));
+$ctx1.sendIdx["*"]=2;
+$5=_st($6).__slash(t1);
+$ctx1.sendIdx["/"]=1;
+$4=_st($5)._printString();
+$ctx1.sendIdx["printString"]=1;
+$3=_st($4).__comma(" bytecodes/sec; ");
+$2=_st($3).__comma(_st(_st(_st(r).__star((1000))).__slash(t2))._printString());
+$ctx1.sendIdx[","]=2;
+$1=_st($2).__comma(" sends/sec");
+$ctx1.sendIdx[","]=1;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"tinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2},smalltalk.Number)})},
+}, function($ctx1) {$ctx1.fill(self,"tinyBenchmarks",{t1:t1,t2:t2,r:r,n1:n1,n2:n2},globals.Number)})},
 args: [],
 source: "tinyBenchmarks\x0a\x09\x22Report the results of running the two tiny Squeak benchmarks.\x0a\x09ar 9/10/1999: Adjusted to run at least 1 sec to get more stable results\x22\x0a\x09\x220 tinyBenchmarks\x22\x0a\x09\x22On a 292 MHz G3 Mac: 22727272 bytecodes/sec; 984169 sends/sec\x22\x0a\x09\x22On a 400 MHz PII/Win98: 18028169 bytecodes/sec; 1081272 sends/sec\x22\x0a\x09| t1 t2 r n1 n2 |\x0a\x09n1 := 1.\x0a\x09[t1 := Date millisecondsToRun: [n1 benchmark].\x0a\x09t1 < 1000] whileTrue:[n1 := n1 * 2]. \x22Note: #benchmark's runtime is about O(n)\x22\x0a\x0a\x09n2 := 16.\x0a\x09[t2 := Date millisecondsToRun: [r := n2 benchFib].\x0a\x09t2 < 1000] whileTrue:[n2 := n2 + 1].\x0a\x09\x22Note: #benchFib's runtime is about O(k^n),\x0a\x09\x09where k is the golden number = (1 + 5 sqrt) / 2 = 1.618....\x22\x0a\x0a\x09^ ((n1 * 500000 * 1000) / t1) printString, ' bytecodes/sec; ',\x0a\x09\x09((r * 1000) / t2) printString, ' sends/sec'",
 messageSends: ["whileTrue:", "millisecondsToRun:", "benchmark", "<", "*", "benchFib", "+", ",", "printString", "/"],
 referencedClasses: ["Date"]
 }),
-smalltalk.Number);
+globals.Number);
 
 });

File diff suppressed because it is too large
+ 259 - 254
js/Canvas.js


File diff suppressed because it is too large
+ 384 - 184
js/Compiler-AST.js


+ 285 - 258
js/Compiler-Core.js

@@ -1,134 +1,110 @@
-define("amber_core/Compiler-Core", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Compiler-Core", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects", "amber_core/Kernel-Collections"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Compiler-Core');
 smalltalk.packages["Compiler-Core"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('AbstractCodeGenerator', smalltalk.Object, ['currentClass', 'source'], 'Compiler-Core');
-smalltalk.AbstractCodeGenerator.comment="I am the abstract super class of all code generators and provide their common API.";
+smalltalk.addClass('AbstractCodeGenerator', globals.Object, ['currentClass', 'source'], 'Compiler-Core');
+globals.AbstractCodeGenerator.comment="I am the abstract super class of all code generators and provide their common API.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "classNameFor:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$1;
+var $2,$3,$4,$1;
 $2=_st(aClass)._isMetaclass();
 if(smalltalk.assert($2)){
-$1=_st(_st(_st(aClass)._instanceClass())._name()).__comma(".klass");
+$3=_st(_st(aClass)._instanceClass())._name();
+$ctx1.sendIdx["name"]=1;
+$1=_st($3).__comma(".klass");
 } else {
-$3=_st(aClass)._isNil();
-if(smalltalk.assert($3)){
+$4=_st(aClass)._isNil();
+if(smalltalk.assert($4)){
 $1="nil";
 } else {
 $1=_st(aClass)._name();
 };
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass},smalltalk.AbstractCodeGenerator)})},
+}, function($ctx1) {$ctx1.fill(self,"classNameFor:",{aClass:aClass},globals.AbstractCodeGenerator)})},
 args: ["aClass"],
-source: "classNameFor: aClass\x0a\x09^aClass isMetaclass\x0a\x09\x09ifTrue: [aClass instanceClass name, '.klass']\x0a\x09\x09ifFalse: [\x0a\x09\x09aClass isNil\x0a\x09\x09\x09ifTrue: ['nil']\x0a\x09\x09\x09ifFalse: [aClass name]]",
+source: "classNameFor: aClass\x0a\x09^ aClass isMetaclass\x0a\x09\x09ifTrue: [ aClass instanceClass name, '.klass' ]\x0a\x09\x09ifFalse: [\x0a\x09\x09aClass isNil\x0a\x09\x09\x09ifTrue: [ 'nil' ]\x0a\x09\x09\x09ifFalse: [ aClass name ]]",
 messageSends: ["ifTrue:ifFalse:", "isMetaclass", ",", "name", "instanceClass", "isNil"],
 referencedClasses: []
 }),
-smalltalk.AbstractCodeGenerator);
+globals.AbstractCodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "compileNode:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._subclassResponsibility();
-return self}, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode},smalltalk.AbstractCodeGenerator)})},
+return self}, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode},globals.AbstractCodeGenerator)})},
 args: ["aNode"],
 source: "compileNode: aNode\x0a\x09self subclassResponsibility",
 messageSends: ["subclassResponsibility"],
 referencedClasses: []
 }),
-smalltalk.AbstractCodeGenerator);
+globals.AbstractCodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "currentClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@currentClass"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"currentClass",{},smalltalk.AbstractCodeGenerator)})},
+},
 args: [],
-source: "currentClass\x0a\x09^currentClass",
+source: "currentClass\x0a\x09^ currentClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.AbstractCodeGenerator);
+globals.AbstractCodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "currentClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@currentClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"currentClass:",{aClass:aClass},smalltalk.AbstractCodeGenerator)})},
+return self},
 args: ["aClass"],
 source: "currentClass: aClass\x0a\x09currentClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.AbstractCodeGenerator);
+globals.AbstractCodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "pseudoVariables",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(_st($Smalltalk())._current())._pseudoVariableNames();
+$1=_st($Smalltalk())._pseudoVariableNames();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"pseudoVariables",{},smalltalk.AbstractCodeGenerator)})},
+}, function($ctx1) {$ctx1.fill(self,"pseudoVariables",{},globals.AbstractCodeGenerator)})},
 args: [],
-source: "pseudoVariables\x0a\x09^ Smalltalk current pseudoVariableNames",
-messageSends: ["pseudoVariableNames", "current"],
+source: "pseudoVariables\x0a\x09^ Smalltalk pseudoVariableNames",
+messageSends: ["pseudoVariableNames"],
 referencedClasses: ["Smalltalk"]
 }),
-smalltalk.AbstractCodeGenerator);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "safeVariableNameFor:",
-category: 'accessing',
-fn: function (aString){
-var self=this;
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
-return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=_st(_st(_st($Smalltalk())._current())._reservedWords())._includes_(aString);
-if(smalltalk.assert($2)){
-$1=_st(aString).__comma("_");
-} else {
-$1=aString;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"safeVariableNameFor:",{aString:aString},smalltalk.AbstractCodeGenerator)})},
-args: ["aString"],
-source: "safeVariableNameFor: aString\x0a\x09^(Smalltalk current reservedWords includes: aString)\x0a\x09\x09ifTrue: [aString, '_']\x0a\x09\x09ifFalse: [aString]",
-messageSends: ["ifTrue:ifFalse:", "includes:", "reservedWords", "current", ","],
-referencedClasses: ["Smalltalk"]
-}),
-smalltalk.AbstractCodeGenerator);
+globals.AbstractCodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "source",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -140,104 +116,105 @@ $1="";
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"source",{},smalltalk.AbstractCodeGenerator)})},
+}, function($ctx1) {$ctx1.fill(self,"source",{},globals.AbstractCodeGenerator)})},
 args: [],
-source: "source\x0a\x09^source ifNil: ['']",
+source: "source\x0a\x09^ source ifNil: [ '' ]",
 messageSends: ["ifNil:"],
 referencedClasses: []
 }),
-smalltalk.AbstractCodeGenerator);
+globals.AbstractCodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "source:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@source"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"source:",{aString:aString},smalltalk.AbstractCodeGenerator)})},
+return self},
 args: ["aString"],
 source: "source: aString\x0a\x09source := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.AbstractCodeGenerator);
+globals.AbstractCodeGenerator);
 
 
 
-smalltalk.addClass('CodeGenerator', smalltalk.AbstractCodeGenerator, [], 'Compiler-Core');
-smalltalk.CodeGenerator.comment="I am a basic code generator. I generate a valid JavaScript output, but no not perform any inlining.\x0aSee `InliningCodeGenerator` for an optimized JavaScript code generation.";
+smalltalk.addClass('CodeGenerator', globals.AbstractCodeGenerator, [], 'Compiler-Core');
+globals.CodeGenerator.comment="I am a basic code generator. I generate a valid JavaScript output, but no not perform any inlining.\x0aSee `InliningCodeGenerator` for an optimized JavaScript code generation.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "compileNode:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aNode){
 var self=this;
 var ir,stream;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
 _st(self._semanticAnalyzer())._visit_(aNode);
+$ctx1.sendIdx["visit:"]=1;
 ir=_st(self._translator())._visit_(aNode);
+$ctx1.sendIdx["visit:"]=2;
 $2=self._irTranslator();
 _st($2)._currentClass_(self._currentClass());
 _st($2)._visit_(ir);
 $3=_st($2)._contents();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,ir:ir,stream:stream},smalltalk.CodeGenerator)})},
+}, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,ir:ir,stream:stream},globals.CodeGenerator)})},
 args: ["aNode"],
 source: "compileNode: aNode\x0a\x09| ir stream |\x0a\x09self semanticAnalyzer visit: aNode.\x0a\x09ir := self translator visit: aNode.\x0a\x09^ self irTranslator\x0a\x09\x09currentClass: self currentClass;\x0a\x09\x09visit: ir;\x0a\x09\x09contents",
 messageSends: ["visit:", "semanticAnalyzer", "translator", "currentClass:", "irTranslator", "currentClass", "contents"],
 referencedClasses: []
 }),
-smalltalk.CodeGenerator);
+globals.CodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "irTranslator",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (){
 var self=this;
-function $IRJSTranslator(){return smalltalk.IRJSTranslator||(typeof IRJSTranslator=="undefined"?nil:IRJSTranslator)}
+function $IRJSTranslator(){return globals.IRJSTranslator||(typeof IRJSTranslator=="undefined"?nil:IRJSTranslator)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st($IRJSTranslator())._new();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"irTranslator",{},smalltalk.CodeGenerator)})},
+}, function($ctx1) {$ctx1.fill(self,"irTranslator",{},globals.CodeGenerator)})},
 args: [],
 source: "irTranslator\x0a\x09^ IRJSTranslator new",
 messageSends: ["new"],
 referencedClasses: ["IRJSTranslator"]
 }),
-smalltalk.CodeGenerator);
+globals.CodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "semanticAnalyzer",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (){
 var self=this;
-function $SemanticAnalyzer(){return smalltalk.SemanticAnalyzer||(typeof SemanticAnalyzer=="undefined"?nil:SemanticAnalyzer)}
+function $SemanticAnalyzer(){return globals.SemanticAnalyzer||(typeof SemanticAnalyzer=="undefined"?nil:SemanticAnalyzer)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st($SemanticAnalyzer())._on_(self._currentClass());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"semanticAnalyzer",{},smalltalk.CodeGenerator)})},
+}, function($ctx1) {$ctx1.fill(self,"semanticAnalyzer",{},globals.CodeGenerator)})},
 args: [],
 source: "semanticAnalyzer\x0a\x09^ SemanticAnalyzer on: self currentClass",
 messageSends: ["on:", "currentClass"],
 referencedClasses: ["SemanticAnalyzer"]
 }),
-smalltalk.CodeGenerator);
+globals.CodeGenerator);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "translator",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (){
 var self=this;
-function $IRASTTranslator(){return smalltalk.IRASTTranslator||(typeof IRASTTranslator=="undefined"?nil:IRASTTranslator)}
+function $IRASTTranslator(){return globals.IRASTTranslator||(typeof IRASTTranslator=="undefined"?nil:IRASTTranslator)}
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
 $2=_st($IRASTTranslator())._new();
@@ -246,25 +223,25 @@ _st($2)._theClass_(self._currentClass());
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"translator",{},smalltalk.CodeGenerator)})},
+}, function($ctx1) {$ctx1.fill(self,"translator",{},globals.CodeGenerator)})},
 args: [],
 source: "translator\x0a\x09^ IRASTTranslator new\x0a\x09\x09source: self source;\x0a\x09\x09theClass: self currentClass;\x0a\x09\x09yourself",
 messageSends: ["source:", "new", "source", "theClass:", "currentClass", "yourself"],
 referencedClasses: ["IRASTTranslator"]
 }),
-smalltalk.CodeGenerator);
+globals.CodeGenerator);
 
 
 
-smalltalk.addClass('Compiler', smalltalk.Object, ['currentClass', 'source', 'unknownVariables', 'codeGeneratorClass'], 'Compiler-Core');
-smalltalk.Compiler.comment="I provide the public interface for compiling Amber source code into JavaScript.\x0a\x0aThe code generator used to produce JavaScript can be plugged with `#codeGeneratorClass`.\x0aThe default code generator is an instance of `InlinedCodeGenerator`";
+smalltalk.addClass('Compiler', globals.Object, ['currentClass', 'source', 'unknownVariables', 'codeGeneratorClass'], 'Compiler-Core');
+globals.Compiler.comment="I provide the public interface for compiling Amber source code into JavaScript.\x0a\x0aThe code generator used to produce JavaScript can be plugged with `#codeGeneratorClass`.\x0aThe default code generator is an instance of `InlinedCodeGenerator`";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "codeGeneratorClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-function $InliningCodeGenerator(){return smalltalk.InliningCodeGenerator||(typeof InliningCodeGenerator=="undefined"?nil:InliningCodeGenerator)}
+function $InliningCodeGenerator(){return globals.InliningCodeGenerator||(typeof InliningCodeGenerator=="undefined"?nil:InliningCodeGenerator)}
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
 $2=self["@codeGeneratorClass"];
@@ -274,52 +251,51 @@ $1=$InliningCodeGenerator();
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"codeGeneratorClass",{},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"codeGeneratorClass",{},globals.Compiler)})},
 args: [],
-source: "codeGeneratorClass\x0a\x09^codeGeneratorClass ifNil: [InliningCodeGenerator]",
+source: "codeGeneratorClass\x0a\x09^ codeGeneratorClass ifNil: [ InliningCodeGenerator ]",
 messageSends: ["ifNil:"],
 referencedClasses: ["InliningCodeGenerator"]
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "codeGeneratorClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@codeGeneratorClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"codeGeneratorClass:",{aClass:aClass},smalltalk.Compiler)})},
+return self},
 args: ["aClass"],
 source: "codeGeneratorClass: aClass\x0a\x09codeGeneratorClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "compile:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._compileNode_(self._parse_(aString));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"compile:",{aString:aString},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"compile:",{aString:aString},globals.Compiler)})},
 args: ["aString"],
-source: "compile: aString\x0a\x09^self compileNode: (self parse: aString)",
+source: "compile: aString\x0a\x09^ self compileNode: (self parse: aString)",
 messageSends: ["compileNode:", "parse:"],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "compile:forClass:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString,aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -328,59 +304,63 @@ self._currentClass_(aClass);
 self._source_(aString);
 $1=self._compile_(aString);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"compile:forClass:",{aString:aString,aClass:aClass},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"compile:forClass:",{aString:aString,aClass:aClass},globals.Compiler)})},
 args: ["aString", "aClass"],
-source: "compile: aString forClass: aClass\x0a\x09self currentClass: aClass.\x0a\x09self source: aString.\x0a\x09^self compile: aString",
+source: "compile: aString forClass: aClass\x0a\x09self currentClass: aClass.\x0a\x09self source: aString.\x0a\x09^ self compile: aString",
 messageSends: ["currentClass:", "source:", "compile:"],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "compileExpression:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString){
 var self=this;
-function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
+function $DoIt(){return globals.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $1,$2;
 self._currentClass_($DoIt());
-self._source_(_st("doIt ^[".__comma(aString)).__comma("] value"));
-$1=self._compileNode_(self._parse_(self._source()));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"compileExpression:",{aString:aString},smalltalk.Compiler)})},
+$1=_st("doIt ^ [ ".__comma(aString)).__comma(" ] value");
+$ctx1.sendIdx[","]=1;
+self._source_($1);
+$2=self._compileNode_(self._parse_(self._source()));
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"compileExpression:",{aString:aString},globals.Compiler)})},
 args: ["aString"],
-source: "compileExpression: aString\x0a\x09self currentClass: DoIt.\x0a\x09self source: 'doIt ^[', aString, '] value'.\x0a\x09^self compileNode: (self parse: self source)",
+source: "compileExpression: aString\x0a\x09self currentClass: DoIt.\x0a\x09self source: 'doIt ^ [ ', aString, ' ] value'.\x0a\x09^ self compileNode: (self parse: self source)",
 messageSends: ["currentClass:", "source:", ",", "compileNode:", "parse:", "source"],
 referencedClasses: ["DoIt"]
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "compileExpression:on:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString,anObject){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $1,$2;
 self._currentClass_(_st(anObject)._class());
-self._source_(_st("xxxDoIt ^[".__comma(aString)).__comma("] value"));
-$1=self._compileNode_(self._parse_(self._source()));
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"compileExpression:on:",{aString:aString,anObject:anObject},smalltalk.Compiler)})},
+$1=_st("xxxDoIt ^ [ ".__comma(aString)).__comma(" ] value");
+$ctx1.sendIdx[","]=1;
+self._source_($1);
+$2=self._compileNode_(self._parse_(self._source()));
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"compileExpression:on:",{aString:aString,anObject:anObject},globals.Compiler)})},
 args: ["aString", "anObject"],
-source: "compileExpression: aString on: anObject\x0a\x09self currentClass: anObject class.\x0a\x09self source: 'xxxDoIt ^[', aString, '] value'.\x0a\x09^self compileNode: (self parse: self source)",
+source: "compileExpression: aString on: anObject\x0a\x09self currentClass: anObject class.\x0a\x09self source: 'xxxDoIt ^ [ ', aString, ' ] value'.\x0a\x09^ self compileNode: (self parse: self source)",
 messageSends: ["currentClass:", "class", "source:", ",", "compileNode:", "parse:", "source"],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "compileNode:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aNode){
 var self=this;
 var generator,result;
@@ -394,211 +374,213 @@ result=_st(generator)._compileNode_(aNode);
 self._unknownVariables_([]);
 $3=result;
 return $3;
-}, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,generator:generator,result:result},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"compileNode:",{aNode:aNode,generator:generator,result:result},globals.Compiler)})},
 args: ["aNode"],
-source: "compileNode: aNode\x0a\x09| generator result |\x0a\x09generator := self codeGeneratorClass new.\x0a\x09generator\x0a\x09\x09source: self source;\x0a\x09\x09currentClass: self currentClass.\x0a\x09result := generator compileNode: aNode.\x0a\x09self unknownVariables: #().\x0a\x09^result",
+source: "compileNode: aNode\x0a\x09| generator result |\x0a\x09generator := self codeGeneratorClass new.\x0a\x09generator\x0a\x09\x09source: self source;\x0a\x09\x09currentClass: self currentClass.\x0a\x09result := generator compileNode: aNode.\x0a\x09self unknownVariables: #().\x0a\x09^ result",
 messageSends: ["new", "codeGeneratorClass", "source:", "source", "currentClass:", "currentClass", "compileNode:", "unknownVariables:"],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "currentClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@currentClass"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"currentClass",{},smalltalk.Compiler)})},
+},
 args: [],
-source: "currentClass\x0a\x09^currentClass",
+source: "currentClass\x0a\x09^ currentClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "currentClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@currentClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"currentClass:",{aClass:aClass},smalltalk.Compiler)})},
+return self},
 args: ["aClass"],
 source: "currentClass: aClass\x0a\x09currentClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "eval:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 return eval(aString);
-return self}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString},smalltalk.Compiler)})},
+return self}, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString},globals.Compiler)})},
 args: ["aString"],
 source: "eval: aString\x0a\x09<return eval(aString)>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "evaluateExpression:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString){
 var self=this;
-function $DoIt(){return smalltalk.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
+function $DoIt(){return globals.DoIt||(typeof DoIt=="undefined"?nil:DoIt)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._evaluateExpression_on_(aString,_st($DoIt())._new());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:",{aString:aString},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:",{aString:aString},globals.Compiler)})},
 args: ["aString"],
 source: "evaluateExpression: aString\x0a\x09\x22Unlike #eval: evaluate a Smalltalk expression and answer the returned object\x22\x0a\x09^ self evaluateExpression: aString on: DoIt new",
 messageSends: ["evaluateExpression:on:", "new"],
 referencedClasses: ["DoIt"]
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "evaluateExpression:on:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString,anObject){
 var self=this;
 var result,method;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $1,$2;
 method=self._eval_(self._compileExpression_on_(aString,anObject));
-_st(method)._category_("xxxDoIt");
-_st(_st(anObject)._class())._addCompiledMethod_(method);
+_st(method)._protocol_("xxxDoIt");
+$1=_st(anObject)._class();
+$ctx1.sendIdx["class"]=1;
+_st($1)._addCompiledMethod_(method);
 result=_st(anObject)._xxxDoIt();
 _st(_st(anObject)._class())._removeCompiledMethod_(method);
-$1=result;
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:on:",{aString:aString,anObject:anObject,result:result,method:method},smalltalk.Compiler)})},
+$2=result;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"evaluateExpression:on:",{aString:aString,anObject:anObject,result:result,method:method},globals.Compiler)})},
 args: ["aString", "anObject"],
-source: "evaluateExpression: aString on: anObject\x0a\x09\x22Unlike #eval: evaluate a Smalltalk expression with anObject as the receiver and answer the returned object\x22\x0a\x09| result method |\x0a\x09method := self eval: (self compileExpression: aString on: anObject).\x0a\x09method category: 'xxxDoIt'.\x0a\x09anObject class addCompiledMethod: method.\x0a\x09result := anObject xxxDoIt.\x0a\x09anObject class removeCompiledMethod: method.\x0a\x09^result",
-messageSends: ["eval:", "compileExpression:on:", "category:", "addCompiledMethod:", "class", "xxxDoIt", "removeCompiledMethod:"],
+source: "evaluateExpression: aString on: anObject\x0a\x09\x22Unlike #eval: evaluate a Smalltalk expression with anObject as the receiver and answer the returned object\x22\x0a\x09| result method |\x0a\x09method := self eval: (self compileExpression: aString on: anObject).\x0a\x09method protocol: 'xxxDoIt'.\x0a\x09anObject class addCompiledMethod: method.\x0a\x09result := anObject xxxDoIt.\x0a\x09anObject class removeCompiledMethod: method.\x0a\x09^ result",
+messageSends: ["eval:", "compileExpression:on:", "protocol:", "addCompiledMethod:", "class", "xxxDoIt", "removeCompiledMethod:"],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "install:forClass:category:",
-category: 'compiling',
+selector: "install:forClass:protocol:",
+protocol: 'compiling',
 fn: function (aString,aBehavior,anotherString){
 var self=this;
-function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="undefined"?nil:ClassBuilder)}
+function $ClassBuilder(){return globals.ClassBuilder||(typeof ClassBuilder=="undefined"?nil:ClassBuilder)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(_st($ClassBuilder())._new())._installMethod_forClass_category_(self._eval_(self._compile_forClass_(aString,aBehavior)),aBehavior,anotherString);
+$1=_st(_st($ClassBuilder())._new())._installMethod_forClass_protocol_(self._eval_(self._compile_forClass_(aString,aBehavior)),aBehavior,anotherString);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"install:forClass:category:",{aString:aString,aBehavior:aBehavior,anotherString:anotherString},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"install:forClass:protocol:",{aString:aString,aBehavior:aBehavior,anotherString:anotherString},globals.Compiler)})},
 args: ["aString", "aBehavior", "anotherString"],
-source: "install: aString forClass: aBehavior category: anotherString\x0a\x09^ ClassBuilder new\x0a\x09\x09installMethod: (self eval: (self compile: aString forClass: aBehavior))\x0a\x09\x09forClass: aBehavior\x0a\x09\x09category: anotherString",
-messageSends: ["installMethod:forClass:category:", "new", "eval:", "compile:forClass:"],
+source: "install: aString forClass: aBehavior protocol: anotherString\x0a\x09^ ClassBuilder new\x0a\x09\x09installMethod: (self eval: (self compile: aString forClass: aBehavior))\x0a\x09\x09forClass: aBehavior\x0a\x09\x09protocol: anotherString",
+messageSends: ["installMethod:forClass:protocol:", "new", "eval:", "compile:forClass:"],
 referencedClasses: ["ClassBuilder"]
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "parse:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString){
 var self=this;
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(_st($Smalltalk())._current())._parse_(aString);
+$1=_st($Smalltalk())._parse_(aString);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"parse:",{aString:aString},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"parse:",{aString:aString},globals.Compiler)})},
 args: ["aString"],
-source: "parse: aString\x0a\x09^Smalltalk current parse: aString",
-messageSends: ["parse:", "current"],
+source: "parse: aString\x0a\x09^ Smalltalk parse: aString",
+messageSends: ["parse:"],
 referencedClasses: ["Smalltalk"]
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "parseExpression:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=self._parse_(_st("doIt ^[".__comma(aString)).__comma("] value"));
+var $2,$1;
+$2=_st("doIt ^ [ ".__comma(aString)).__comma(" ] value");
+$ctx1.sendIdx[","]=1;
+$1=self._parse_($2);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"parseExpression:",{aString:aString},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"parseExpression:",{aString:aString},globals.Compiler)})},
 args: ["aString"],
-source: "parseExpression: aString\x0a\x09^self parse: 'doIt ^[', aString, '] value'",
+source: "parseExpression: aString\x0a\x09^ self parse: 'doIt ^ [ ', aString, ' ] value'",
 messageSends: ["parse:", ","],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "recompile:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 _st(_st(_st(aClass)._methodDictionary())._values())._do_displayingProgress_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return self._install_forClass_category_(_st(each)._source(),aClass,_st(each)._category());
+return self._install_forClass_protocol_(_st(each)._source(),aClass,_st(each)._protocol());
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}),"Recompiling ".__comma(_st(aClass)._name()));
 $1=_st(aClass)._isMetaclass();
 if(! smalltalk.assert($1)){
 self._recompile_(_st(aClass)._class());
 };
-return self}, function($ctx1) {$ctx1.fill(self,"recompile:",{aClass:aClass},smalltalk.Compiler)})},
+return self}, function($ctx1) {$ctx1.fill(self,"recompile:",{aClass:aClass},globals.Compiler)})},
 args: ["aClass"],
-source: "recompile: aClass\x0a\x09aClass methodDictionary values\x0a\x09\x09do: [ :each | self install: each source forClass: aClass category: each category ]\x0a\x09\x09displayingProgress: 'Recompiling ', aClass name.\x0a\x09\x22self setupClass: aClass.\x22\x0a\x09aClass isMetaclass ifFalse: [ self recompile: aClass class ]",
-messageSends: ["do:displayingProgress:", "values", "methodDictionary", "install:forClass:category:", "source", "category", ",", "name", "ifFalse:", "isMetaclass", "recompile:", "class"],
+source: "recompile: aClass\x0a\x09aClass methodDictionary values\x0a\x09\x09do: [ :each | \x0a\x09\x09\x09self \x0a\x09\x09\x09\x09install: each source \x0a\x09\x09\x09\x09forClass: aClass \x0a\x09\x09\x09\x09protocol: each protocol ]\x0a\x09\x09displayingProgress: 'Recompiling ', aClass name.\x0a\x09aClass isMetaclass ifFalse: [ self recompile: aClass class ]",
+messageSends: ["do:displayingProgress:", "values", "methodDictionary", "install:forClass:protocol:", "source", "protocol", ",", "name", "ifFalse:", "isMetaclass", "recompile:", "class"],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "recompileAll",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (){
 var self=this;
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(_st($Smalltalk())._current())._classes())._do_displayingProgress_((function(each){
+_st(_st($Smalltalk())._classes())._do_displayingProgress_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return self._recompile_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}),"Compiling all classes...");
-return self}, function($ctx1) {$ctx1.fill(self,"recompileAll",{},smalltalk.Compiler)})},
+return self}, function($ctx1) {$ctx1.fill(self,"recompileAll",{},globals.Compiler)})},
 args: [],
-source: "recompileAll\x0a\x09Smalltalk current classes \x0a\x09\x09do: [:each | self recompile: each ]\x0a\x09\x09displayingProgress: 'Compiling all classes...'",
-messageSends: ["do:displayingProgress:", "classes", "current", "recompile:"],
+source: "recompileAll\x0a\x09Smalltalk classes \x0a\x09\x09do: [ :each | self recompile: each ]\x0a\x09\x09displayingProgress: 'Compiling all classes...'",
+messageSends: ["do:displayingProgress:", "classes", "recompile:"],
 referencedClasses: ["Smalltalk"]
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "source",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -610,130 +592,151 @@ $1="";
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"source",{},smalltalk.Compiler)})},
+}, function($ctx1) {$ctx1.fill(self,"source",{},globals.Compiler)})},
 args: [],
-source: "source\x0a\x09^source ifNil: ['']",
+source: "source\x0a\x09^ source ifNil: [ '' ]",
 messageSends: ["ifNil:"],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "source:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@source"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"source:",{aString:aString},smalltalk.Compiler)})},
+return self},
 args: ["aString"],
 source: "source: aString\x0a\x09source := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "unknownVariables",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@unknownVariables"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"unknownVariables",{},smalltalk.Compiler)})},
+},
 args: [],
-source: "unknownVariables\x0a\x09^unknownVariables",
+source: "unknownVariables\x0a\x09^ unknownVariables",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "unknownVariables:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aCollection){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@unknownVariables"]=aCollection;
-return self}, function($ctx1) {$ctx1.fill(self,"unknownVariables:",{aCollection:aCollection},smalltalk.Compiler)})},
+return self},
 args: ["aCollection"],
 source: "unknownVariables: aCollection\x0a\x09unknownVariables := aCollection",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Compiler);
+globals.Compiler);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "recompile:",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (aClass){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._new())._recompile_(aClass);
-return self}, function($ctx1) {$ctx1.fill(self,"recompile:",{aClass:aClass},smalltalk.Compiler.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"recompile:",{aClass:aClass},globals.Compiler.klass)})},
 args: ["aClass"],
 source: "recompile: aClass\x0a\x09self new recompile: aClass",
 messageSends: ["recompile:", "new"],
 referencedClasses: []
 }),
-smalltalk.Compiler.klass);
+globals.Compiler.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "recompileAll",
-category: 'compiling',
+protocol: 'compiling',
 fn: function (){
 var self=this;
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(_st($Smalltalk())._current())._classes())._do_((function(each){
+_st(_st($Smalltalk())._classes())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return self._recompile_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"recompileAll",{},smalltalk.Compiler.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"recompileAll",{},globals.Compiler.klass)})},
 args: [],
-source: "recompileAll\x0a\x09Smalltalk current classes do: [:each |\x0a\x09\x09self recompile: each]",
-messageSends: ["do:", "classes", "current", "recompile:"],
+source: "recompileAll\x0a\x09Smalltalk classes do: [ :each |\x0a\x09\x09self recompile: each ]",
+messageSends: ["do:", "classes", "recompile:"],
 referencedClasses: ["Smalltalk"]
 }),
-smalltalk.Compiler.klass);
+globals.Compiler.klass);
+
 
+smalltalk.addClass('DoIt', globals.Object, [], 'Compiler-Core');
+globals.DoIt.comment="`DoIt` is the class used to compile and evaluate expressions. See `Compiler >> evaluateExpression:`.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "foo",
+protocol: 'tests',
+fn: function (){
+var self=this;
+function $Array(){return globals.Array||(typeof Array=="undefined"?nil:Array)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=_st($Array())._new();
+_st($2)._add_((3));
+$ctx1.sendIdx["add:"]=1;
+_st($2)._add_((4));
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"foo",{},globals.DoIt)})},
+args: [],
+source: "foo ^ Array new add: 3; add: 4; yourself",
+messageSends: ["add:", "new", "yourself"],
+referencedClasses: ["Array"]
+}),
+globals.DoIt);
 
-smalltalk.addClass('DoIt', smalltalk.Object, [], 'Compiler-Core');
-smalltalk.DoIt.comment="`DoIt` is the class used to compile and evaluate expressions. See `Compiler >> evaluateExpression:`.";
 
 
-smalltalk.addClass('NodeVisitor', smalltalk.Object, [], 'Compiler-Core');
-smalltalk.NodeVisitor.comment="I am the abstract super class of all AST node visitors.";
+smalltalk.addClass('NodeVisitor', globals.Object, [], 'Compiler-Core');
+globals.NodeVisitor.comment="I am the abstract super class of all AST node visitors.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visit:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(aNode)._accept_(self);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visit:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visit:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visit: aNode\x0a\x09^ aNode accept: self",
 messageSends: ["accept:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitAll:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aCollection){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -743,265 +746,289 @@ return smalltalk.withContext(function($ctx2) {
 return self._visit_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitAll:",{aCollection:aCollection},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitAll:",{aCollection:aCollection},globals.NodeVisitor)})},
 args: ["aCollection"],
 source: "visitAll: aCollection\x0a\x09^ aCollection collect: [ :each | self visit: each ]",
 messageSends: ["collect:", "visit:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitAssignmentNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitAssignmentNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitAssignmentNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitBlockNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitBlockNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitBlockNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitBlockSequenceNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitSequenceNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitBlockSequenceNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitBlockSequenceNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitBlockSequenceNode: aNode\x0a\x09^ self visitSequenceNode: aNode",
 messageSends: ["visitSequenceNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitCascadeNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitCascadeNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitCascadeNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitCascadeNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitDynamicArrayNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitDynamicArrayNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitDynamicArrayNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitDynamicArrayNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitDynamicDictionaryNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitDynamicDictionaryNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitDynamicDictionaryNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitJSStatementNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitJSStatementNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitJSStatementNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitJSStatementNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitMethodNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitMethodNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitMethodNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitMethodNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitAll_(_st(aNode)._nodes());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitNode: aNode\x0a\x09^ self visitAll: aNode nodes",
 messageSends: ["visitAll:", "nodes"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitReturnNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitReturnNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitReturnNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitReturnNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitSendNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitSendNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitSendNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitSequenceNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitSequenceNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitSequenceNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitValueNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitValueNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitValueNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitValueNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "visitVariableNode:",
-category: 'visiting',
+protocol: 'visiting',
 fn: function (aNode){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._visitNode_(aNode);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode},smalltalk.NodeVisitor)})},
+}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode},globals.NodeVisitor)})},
 args: ["aNode"],
 source: "visitVariableNode: aNode\x0a\x09^ self visitNode: aNode",
 messageSends: ["visitNode:"],
 referencedClasses: []
 }),
-smalltalk.NodeVisitor);
+globals.NodeVisitor);
 
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "asVariableName",
+protocol: '*Compiler-Core',
+fn: function (){
+var self=this;
+function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=_st(_st($Smalltalk())._reservedWords())._includes_(self);
+if(smalltalk.assert($2)){
+$1=self.__comma("_");
+} else {
+$1=self;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"asVariableName",{},globals.String)})},
+args: [],
+source: "asVariableName\x0a\x09^ (Smalltalk reservedWords includes: self)\x0a\x09\x09ifTrue: [ self, '_' ]\x0a\x09\x09ifFalse: [ self ]",
+messageSends: ["ifTrue:ifFalse:", "includes:", "reservedWords", ","],
+referencedClasses: ["Smalltalk"]
+}),
+globals.String);
+
 });

+ 55 - 59
js/Compiler-Exceptions.js

@@ -1,225 +1,221 @@
-define("amber_core/Compiler-Exceptions", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Exceptions"], function(smalltalk,nil,_st){
+define("amber_core/Compiler-Exceptions", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Exceptions", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Compiler-Exceptions');
 smalltalk.packages["Compiler-Exceptions"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('CompilerError', smalltalk.Error, [], 'Compiler-Exceptions');
-smalltalk.CompilerError.comment="I am the common superclass of all compiling errors.";
+smalltalk.addClass('CompilerError', globals.Error, [], 'Compiler-Exceptions');
+globals.CompilerError.comment="I am the common superclass of all compiling errors.";
 
 
-smalltalk.addClass('ParseError', smalltalk.CompilerError, [], 'Compiler-Exceptions');
-smalltalk.ParseError.comment="Instance of ParseError are signaled on any parsing error.\x0aSee `Smalltalk >> #parse:`";
+smalltalk.addClass('ParseError', globals.CompilerError, [], 'Compiler-Exceptions');
+globals.ParseError.comment="Instance of ParseError are signaled on any parsing error.\x0aSee `Smalltalk >> #parse:`";
 
 
-smalltalk.addClass('SemanticError', smalltalk.CompilerError, [], 'Compiler-Exceptions');
-smalltalk.SemanticError.comment="I represent an abstract semantic error thrown by the SemanticAnalyzer.\x0aSemantic errors can be unknown variable errors, etc.\x0aSee my subclasses for concrete errors.\x0a\x0aThe IDE should catch instances of Semantic error to deal with them when compiling";
+smalltalk.addClass('SemanticError', globals.CompilerError, [], 'Compiler-Exceptions');
+globals.SemanticError.comment="I represent an abstract semantic error thrown by the SemanticAnalyzer.\x0aSemantic errors can be unknown variable errors, etc.\x0aSee my subclasses for concrete errors.\x0a\x0aThe IDE should catch instances of Semantic error to deal with them when compiling";
 
 
-smalltalk.addClass('InliningError', smalltalk.SemanticError, [], 'Compiler-Exceptions');
-smalltalk.InliningError.comment="Instances of InliningError are signaled when using an `InliningCodeGenerator`in a `Compiler`.";
+smalltalk.addClass('InliningError', globals.SemanticError, [], 'Compiler-Exceptions');
+globals.InliningError.comment="Instances of InliningError are signaled when using an `InliningCodeGenerator`in a `Compiler`.";
 
 
-smalltalk.addClass('InvalidAssignmentError', smalltalk.SemanticError, ['variableName'], 'Compiler-Exceptions');
-smalltalk.InvalidAssignmentError.comment="I get signaled when a pseudo variable gets assigned.";
+smalltalk.addClass('InvalidAssignmentError', globals.SemanticError, ['variableName'], 'Compiler-Exceptions');
+globals.InvalidAssignmentError.comment="I get signaled when a pseudo variable gets assigned.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=" Invalid assignment to variable: ".__comma(self._variableName());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"messageText",{},smalltalk.InvalidAssignmentError)})},
+}, function($ctx1) {$ctx1.fill(self,"messageText",{},globals.InvalidAssignmentError)})},
 args: [],
 source: "messageText\x0a\x09^ ' Invalid assignment to variable: ', self variableName",
 messageSends: [",", "variableName"],
 referencedClasses: []
 }),
-smalltalk.InvalidAssignmentError);
+globals.InvalidAssignmentError);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@variableName"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"variableName",{},smalltalk.InvalidAssignmentError)})},
+},
 args: [],
 source: "variableName\x0a\x09^ variableName",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.InvalidAssignmentError);
+globals.InvalidAssignmentError);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@variableName"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString},smalltalk.InvalidAssignmentError)})},
+return self},
 args: ["aString"],
 source: "variableName: aString\x0a\x09variableName := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.InvalidAssignmentError);
+globals.InvalidAssignmentError);
 
 
 
-smalltalk.addClass('ShadowingVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Exceptions');
-smalltalk.ShadowingVariableError.comment="I get signaled when a variable in a block or method scope shadows a variable of the same name in an outer scope.";
+smalltalk.addClass('ShadowingVariableError', globals.SemanticError, ['variableName'], 'Compiler-Exceptions');
+globals.ShadowingVariableError.comment="I get signaled when a variable in a block or method scope shadows a variable of the same name in an outer scope.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st("Variable shadowing error: ".__comma(self._variableName())).__comma(" is already defined");
+$ctx1.sendIdx[","]=1;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"messageText",{},smalltalk.ShadowingVariableError)})},
+}, function($ctx1) {$ctx1.fill(self,"messageText",{},globals.ShadowingVariableError)})},
 args: [],
 source: "messageText\x0a\x09^ 'Variable shadowing error: ', self variableName, ' is already defined'",
 messageSends: [",", "variableName"],
 referencedClasses: []
 }),
-smalltalk.ShadowingVariableError);
+globals.ShadowingVariableError);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@variableName"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"variableName",{},smalltalk.ShadowingVariableError)})},
+},
 args: [],
 source: "variableName\x0a\x09^ variableName",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ShadowingVariableError);
+globals.ShadowingVariableError);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@variableName"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString},smalltalk.ShadowingVariableError)})},
+return self},
 args: ["aString"],
 source: "variableName: aString\x0a\x09variableName := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ShadowingVariableError);
+globals.ShadowingVariableError);
 
 
 
-smalltalk.addClass('UnknownVariableError', smalltalk.SemanticError, ['variableName'], 'Compiler-Exceptions');
-smalltalk.UnknownVariableError.comment="I get signaled when a variable is not defined.\x0aThe default behavior is to allow it, as this is how Amber currently is able to seamlessly send messages to JavaScript objects.";
+smalltalk.addClass('UnknownVariableError', globals.SemanticError, ['variableName'], 'Compiler-Exceptions');
+globals.UnknownVariableError.comment="I get signaled when a variable is not defined.\x0aThe default behavior is to allow it, as this is how Amber currently is able to seamlessly send messages to JavaScript objects.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st("Unknown Variable error: ".__comma(self._variableName())).__comma(" is not defined");
+$ctx1.sendIdx[","]=1;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"messageText",{},smalltalk.UnknownVariableError)})},
+}, function($ctx1) {$ctx1.fill(self,"messageText",{},globals.UnknownVariableError)})},
 args: [],
 source: "messageText\x0a\x09^ 'Unknown Variable error: ', self variableName, ' is not defined'",
 messageSends: [",", "variableName"],
 referencedClasses: []
 }),
-smalltalk.UnknownVariableError);
+globals.UnknownVariableError);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@variableName"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"variableName",{},smalltalk.UnknownVariableError)})},
+},
 args: [],
 source: "variableName\x0a\x09^ variableName",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.UnknownVariableError);
+globals.UnknownVariableError);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@variableName"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString},smalltalk.UnknownVariableError)})},
+return self},
 args: ["aString"],
 source: "variableName: aString\x0a\x09variableName := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.UnknownVariableError);
+globals.UnknownVariableError);
 
 
 
-smalltalk.addClass('RethrowErrorHandler', smalltalk.ErrorHandler, [], 'Compiler-Exceptions');
-smalltalk.RethrowErrorHandler.comment="This class is used in the commandline version of the compiler.\x0aIt uses the handleError: message of ErrorHandler for printing the stacktrace and throws the error again as JS exception.\x0aAs a result Smalltalk errors are not swallowd by the Amber runtime and compilation can be aborted.";
+smalltalk.addClass('RethrowErrorHandler', globals.Object, [], 'Compiler-Exceptions');
+globals.RethrowErrorHandler.comment="This class is used in the commandline version of the compiler.\x0aIt uses the handleError: message of ErrorHandler for printing the stacktrace and throws the error again as JS exception.\x0aAs a result Smalltalk errors are not swallowd by the Amber runtime and compilation can be aborted.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "basicSignal:",
-category: 'error handling',
+protocol: 'error handling',
 fn: function (anError){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 throw anError;
-return self}, function($ctx1) {$ctx1.fill(self,"basicSignal:",{anError:anError},smalltalk.RethrowErrorHandler)})},
+return self}, function($ctx1) {$ctx1.fill(self,"basicSignal:",{anError:anError},globals.RethrowErrorHandler)})},
 args: ["anError"],
-source: "basicSignal: anError\x0a\x09<throw anError>",
+source: "basicSignal: anError\x0a        <throw anError>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.RethrowErrorHandler);
+globals.RethrowErrorHandler);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "handleError:",
-category: 'error handling',
+protocol: 'error handling',
 fn: function (anError){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.RethrowErrorHandler.superclass.fn.prototype._handleError_.apply(_st(self), [anError]);
+globals.RethrowErrorHandler.superclass.fn.prototype._handleError_.apply(_st(self), [anError]);
 self._basicSignal_(anError);
-return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError},smalltalk.RethrowErrorHandler)})},
+return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError},globals.RethrowErrorHandler)})},
 args: ["anError"],
-source: "handleError: anError\x0a\x09super handleError: anError.\x0a\x09self basicSignal: anError",
+source: "handleError: anError\x0a        super handleError: anError.\x0a        self basicSignal: anError",
 messageSends: ["handleError:", "basicSignal:"],
 referencedClasses: []
 }),
-smalltalk.RethrowErrorHandler);
+globals.RethrowErrorHandler);
 
 
 });

File diff suppressed because it is too large
+ 336 - 215
js/Compiler-IR.js


File diff suppressed because it is too large
+ 483 - 324
js/Compiler-Inlining.js


File diff suppressed because it is too large
+ 307 - 235
js/Compiler-Interpreter.js


File diff suppressed because it is too large
+ 236 - 220
js/Compiler-Semantic.js


File diff suppressed because it is too large
+ 399 - 235
js/Compiler-Tests.js


+ 26 - 22
js/Examples.js

@@ -1,13 +1,13 @@
-define("amber_core/Examples", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Canvas"], function(smalltalk,nil,_st){
+define("amber_core/Examples", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Canvas"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Examples');
 smalltalk.packages["Examples"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('Counter', smalltalk.Widget, ['count', 'header'], 'Examples');
-smalltalk.Counter.comment="This is a trivial Widget example mimicking the classic Counter example in Seaside.\x0aIn order to play with it, just evaluate the doit below in a workspace.\x0aThen take a look in the HTML document above the IDE.\x0a\x0a\x09\x09Counter tryExample";
+smalltalk.addClass('Counter', globals.Widget, ['count', 'header'], 'Examples');
+globals.Counter.comment="This is a trivial Widget example mimicking the classic Counter example in Seaside.\x0aIn order to play with it, just evaluate the doit below in a workspace.\x0aThen take a look in the HTML document above the IDE.\x0a\x0a\x09\x09Counter tryExample";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "decrease",
-category: 'actions',
+protocol: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -16,18 +16,18 @@ _st(self["@header"])._contents_((function(html){
 return smalltalk.withContext(function($ctx2) {
 return _st(html)._with_(_st(self["@count"])._asString());
 }, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"decrease",{},smalltalk.Counter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"decrease",{},globals.Counter)})},
 args: [],
-source: "decrease\x0a\x09count := count - 1.\x0a\x09header contents: [:html | html with: count asString]",
+source: "decrease\x0a\x09count := count - 1.\x0a\x09header contents: [ :html | html with: count asString ]",
 messageSends: ["-", "contents:", "with:", "asString"],
 referencedClasses: []
 }),
-smalltalk.Counter);
+globals.Counter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "increase",
-category: 'actions',
+protocol: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -36,78 +36,82 @@ _st(self["@header"])._contents_((function(html){
 return smalltalk.withContext(function($ctx2) {
 return _st(html)._with_(_st(self["@count"])._asString());
 }, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"increase",{},smalltalk.Counter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"increase",{},globals.Counter)})},
 args: [],
-source: "increase\x0a\x09count := count + 1.\x0a\x09header contents: [:html | html with: count asString]",
+source: "increase\x0a\x09count := count + 1.\x0a\x09header contents: [ :html | html with: count asString ]",
 messageSends: ["+", "contents:", "with:", "asString"],
 referencedClasses: []
 }),
-smalltalk.Counter);
+globals.Counter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Counter.superclass.fn.prototype._initialize.apply(_st(self), []);
+globals.Counter.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@count"]=(0);
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Counter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.Counter)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09count := 0",
 messageSends: ["initialize"],
 referencedClasses: []
 }),
-smalltalk.Counter);
+globals.Counter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "renderOn:",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5,$6;
 $1=_st(html)._h1();
 _st($1)._with_(_st(self["@count"])._asString());
+$ctx1.sendIdx["with:"]=1;
 $2=_st($1)._yourself();
 self["@header"]=$2;
 $3=_st(html)._button();
+$ctx1.sendIdx["button"]=1;
 _st($3)._with_("++");
+$ctx1.sendIdx["with:"]=2;
 $4=_st($3)._onClick_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._increase();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+$ctx1.sendIdx["onClick:"]=1;
 $5=_st(html)._button();
 _st($5)._with_("--");
 $6=_st($5)._onClick_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._decrease();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.Counter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},globals.Counter)})},
 args: ["html"],
-source: "renderOn: html\x0a\x09header := html h1\x0a\x09with: count asString;\x0a\x09yourself.\x0a\x09html button\x0a\x09with: '++';\x0a\x09onClick: [self increase].\x0a\x09html button\x0a\x09with: '--';\x0a\x09onClick: [self decrease]",
+source: "renderOn: html\x0a\x09header := html h1\x0a\x09\x09with: count asString;\x0a\x09\x09yourself.\x0a\x09html button\x0a\x09\x09with: '++';\x0a\x09\x09onClick: [ self increase ].\x0a\x09html button\x0a\x09\x09with: '--';\x0a\x09\x09onClick: [ self decrease ]",
 messageSends: ["with:", "h1", "asString", "yourself", "button", "onClick:", "increase", "decrease"],
 referencedClasses: []
 }),
-smalltalk.Counter);
+globals.Counter);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "tryExample",
-category: 'example',
+protocol: 'example',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._new())._appendToJQuery_("body"._asJQuery());
-return self}, function($ctx1) {$ctx1.fill(self,"tryExample",{},smalltalk.Counter.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"tryExample",{},globals.Counter.klass)})},
 args: [],
 source: "tryExample\x0a\x09\x22In order to play with the Counter, just select the\x0a\x09doit below and press the Do it button. Then take a\x0a\x09look in the HTML document above the IDE.\x22\x0a\x0a\x09\x22Counter tryExample\x22\x0a\x09\x09self new appendToJQuery: 'body' asJQuery",
 messageSends: ["appendToJQuery:", "new", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.Counter.klass);
+globals.Counter.klass);
 
 });

+ 158 - 148
js/Helios-Announcements.js

@@ -1,105 +1,100 @@
-define("amber_core/Helios-Announcements", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Announcements", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Announcements');
 smalltalk.packages["Helios-Announcements"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLAboutToChange', smalltalk.Object, ['actionBlock'], 'Helios-Announcements');
+smalltalk.addClass('HLAboutToChange', globals.Object, ['actionBlock'], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "actionBlock",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@actionBlock"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"actionBlock",{},smalltalk.HLAboutToChange)})},
+},
 args: [],
 source: "actionBlock\x0a\x09^ actionBlock",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLAboutToChange);
+globals.HLAboutToChange);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "actionBlock:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@actionBlock"]=aBlock;
-return self}, function($ctx1) {$ctx1.fill(self,"actionBlock:",{aBlock:aBlock},smalltalk.HLAboutToChange)})},
+return self},
 args: ["aBlock"],
 source: "actionBlock: aBlock\x0a\x09actionBlock := aBlock",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLAboutToChange);
+globals.HLAboutToChange);
 
 
 
-smalltalk.addClass('HLAnnouncement', smalltalk.Object, [], 'Helios-Announcements');
-smalltalk.HLAnnouncement.comment="I am the root of the announcement class hierarchy used in the Helios UI.";
+smalltalk.addClass('HLAnnouncement', globals.Object, [], 'Helios-Announcements');
+globals.HLAnnouncement.comment="I am the root of the announcement class hierarchy used in the Helios UI.";
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "heliosClass",
-category: 'helios',
+protocol: 'helios',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "announcement";
-}, function($ctx1) {$ctx1.fill(self,"heliosClass",{},smalltalk.HLAnnouncement.klass)})},
+},
 args: [],
 source: "heliosClass\x0a\x09^ 'announcement'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLAnnouncement.klass);
+globals.HLAnnouncement.klass);
 
 
-smalltalk.addClass('HLCodeHandled', smalltalk.HLAnnouncement, ['code'], 'Helios-Announcements');
-smalltalk.HLCodeHandled.comment="I am the root class of announcements emitted by `HLCodeWidget`s";
+smalltalk.addClass('HLCodeHandled', globals.HLAnnouncement, ['code'], 'Helios-Announcements');
+globals.HLCodeHandled.comment="I am the root class of announcements emitted by `HLCodeWidget`s";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "code",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@code"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"code",{},smalltalk.HLCodeHandled)})},
+},
 args: [],
 source: "code\x0a\x0a\x09^ code",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCodeHandled);
+globals.HLCodeHandled);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "code:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aModel){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@code"]=aModel;
-return self}, function($ctx1) {$ctx1.fill(self,"code:",{aModel:aModel},smalltalk.HLCodeHandled)})},
+return self},
 args: ["aModel"],
 source: "code: aModel\x0a\x0a\x09code := aModel",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCodeHandled);
+globals.HLCodeHandled);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "on:",
-category: 'actions',
+protocol: 'actions',
 fn: function (aCodeModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -109,394 +104,376 @@ _st($2)._code_(aCodeModel);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{aCodeModel:aCodeModel},smalltalk.HLCodeHandled.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:",{aCodeModel:aCodeModel},globals.HLCodeHandled.klass)})},
 args: ["aCodeModel"],
 source: "on: aCodeModel\x0a\x0a\x09^ self new \x0a    \x09code: aCodeModel;\x0a        yourself",
 messageSends: ["code:", "new", "yourself"],
 referencedClasses: []
 }),
-smalltalk.HLCodeHandled.klass);
+globals.HLCodeHandled.klass);
 
 
-smalltalk.addClass('HLDoItExecuted', smalltalk.HLCodeHandled, [], 'Helios-Announcements');
-smalltalk.HLDoItExecuted.comment="I am emitted by a `HLCodeWidget` after a DoIt has been executed.";
+smalltalk.addClass('HLDoItExecuted', globals.HLCodeHandled, [], 'Helios-Announcements');
+globals.HLDoItExecuted.comment="I am emitted by a `HLCodeWidget` after a DoIt has been executed.";
 
 
-smalltalk.addClass('HLDoItRequested', smalltalk.HLCodeHandled, [], 'Helios-Announcements');
-smalltalk.HLDoItRequested.comment="I am emitted by a `HLCodeWidget` before a DoIt is executed.";
+smalltalk.addClass('HLDoItRequested', globals.HLCodeHandled, [], 'Helios-Announcements');
+globals.HLDoItRequested.comment="I am emitted by a `HLCodeWidget` before a DoIt is executed.";
 
 
-smalltalk.addClass('HLInspectItRequested', smalltalk.HLCodeHandled, [], 'Helios-Announcements');
-smalltalk.HLInspectItRequested.comment="I am emitted by a `HLCodeWidget` before an object is inspected.";
+smalltalk.addClass('HLInspectItRequested', globals.HLCodeHandled, [], 'Helios-Announcements');
+globals.HLInspectItRequested.comment="I am emitted by a `HLCodeWidget` before an object is inspected.";
 
 
-smalltalk.addClass('HLPrintItRequested', smalltalk.HLCodeHandled, [], 'Helios-Announcements');
-smalltalk.HLPrintItRequested.comment="I am emitted by a `HLCodeWidget` before an object is printed.";
+smalltalk.addClass('HLPrintItRequested', globals.HLCodeHandled, [], 'Helios-Announcements');
+globals.HLPrintItRequested.comment="I am emitted by a `HLCodeWidget` before an object is printed.";
 
 
-smalltalk.addClass('HLDebuggerAnnouncement', smalltalk.HLAnnouncement, ['context'], 'Helios-Announcements');
+smalltalk.addClass('HLDebuggerAnnouncement', globals.HLAnnouncement, ['context'], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@context"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"context",{},smalltalk.HLDebuggerAnnouncement)})},
+},
 args: [],
 source: "context\x0a\x09^ context",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLDebuggerAnnouncement);
+globals.HLDebuggerAnnouncement);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aContext){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@context"]=aContext;
-return self}, function($ctx1) {$ctx1.fill(self,"context:",{aContext:aContext},smalltalk.HLDebuggerAnnouncement)})},
+return self},
 args: ["aContext"],
 source: "context: aContext\x0a\x09context := aContext",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLDebuggerAnnouncement);
+globals.HLDebuggerAnnouncement);
 
 
 
-smalltalk.addClass('HLDebuggerContextSelected', smalltalk.HLDebuggerAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLDebuggerContextSelected', globals.HLDebuggerAnnouncement, [], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@context"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"context",{},smalltalk.HLDebuggerContextSelected)})},
+},
 args: [],
 source: "context\x0a\x09^ context",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLDebuggerContextSelected);
+globals.HLDebuggerContextSelected);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aContext){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@context"]=aContext;
-return self}, function($ctx1) {$ctx1.fill(self,"context:",{aContext:aContext},smalltalk.HLDebuggerContextSelected)})},
+return self},
 args: ["aContext"],
 source: "context: aContext\x0a\x09context := aContext",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLDebuggerContextSelected);
+globals.HLDebuggerContextSelected);
 
 
 
-smalltalk.addClass('HLDebuggerStepped', smalltalk.HLDebuggerAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLDebuggerStepped', globals.HLDebuggerAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLDebuggerWhere', smalltalk.HLDebuggerAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLDebuggerWhere', globals.HLDebuggerAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLDiveRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLDiveRequested', globals.HLAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLEditComment', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLEditComment', globals.HLAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLErrorRaised', smalltalk.HLAnnouncement, ['error'], 'Helios-Announcements');
+smalltalk.addClass('HLErrorRaised', globals.HLAnnouncement, ['error'], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "error",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@error"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"error",{},smalltalk.HLErrorRaised)})},
+},
 args: [],
 source: "error\x0a\x09^ error",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLErrorRaised);
+globals.HLErrorRaised);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "error:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (anError){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@error"]=anError;
-return self}, function($ctx1) {$ctx1.fill(self,"error:",{anError:anError},smalltalk.HLErrorRaised)})},
+return self},
 args: ["anError"],
 source: "error: anError\x0a\x09error := anError",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLErrorRaised);
+globals.HLErrorRaised);
 
 
 
-smalltalk.addClass('HLCompileErrorRaised', smalltalk.HLErrorRaised, [], 'Helios-Announcements');
+smalltalk.addClass('HLCompileErrorRaised', globals.HLErrorRaised, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLParseErrorRaised', smalltalk.HLErrorRaised, ['line', 'column', 'message'], 'Helios-Announcements');
+smalltalk.addClass('HLParseErrorRaised', globals.HLErrorRaised, ['line', 'column', 'message'], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "column",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@column"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"column",{},smalltalk.HLParseErrorRaised)})},
+},
 args: [],
 source: "column\x0a\x09^ column",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLParseErrorRaised);
+globals.HLParseErrorRaised);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "column:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (anInteger){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@column"]=anInteger;
-return self}, function($ctx1) {$ctx1.fill(self,"column:",{anInteger:anInteger},smalltalk.HLParseErrorRaised)})},
+return self},
 args: ["anInteger"],
 source: "column: anInteger\x0a\x09column := anInteger",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLParseErrorRaised);
+globals.HLParseErrorRaised);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "line",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@line"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"line",{},smalltalk.HLParseErrorRaised)})},
+},
 args: [],
 source: "line\x0a\x09^ line",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLParseErrorRaised);
+globals.HLParseErrorRaised);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "line:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (anInteger){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@line"]=anInteger;
-return self}, function($ctx1) {$ctx1.fill(self,"line:",{anInteger:anInteger},smalltalk.HLParseErrorRaised)})},
+return self},
 args: ["anInteger"],
 source: "line: anInteger\x0a\x09line := anInteger",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLParseErrorRaised);
+globals.HLParseErrorRaised);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "message",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@message"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"message",{},smalltalk.HLParseErrorRaised)})},
+},
 args: [],
 source: "message\x0a\x09^ message",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLParseErrorRaised);
+globals.HLParseErrorRaised);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "message:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@message"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"message:",{aString:aString},smalltalk.HLParseErrorRaised)})},
+return self},
 args: ["aString"],
 source: "message: aString\x0a\x09message := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLParseErrorRaised);
+globals.HLParseErrorRaised);
 
 
 
-smalltalk.addClass('HLUnknownVariableErrorRaised', smalltalk.HLErrorRaised, [], 'Helios-Announcements');
+smalltalk.addClass('HLUnknownVariableErrorRaised', globals.HLErrorRaised, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLFocusRequested', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLFocusRequested', globals.HLAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLClassesFocusRequested', smalltalk.HLFocusRequested, [], 'Helios-Announcements');
+smalltalk.addClass('HLClassesFocusRequested', globals.HLFocusRequested, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLMethodsFocusRequested', smalltalk.HLFocusRequested, [], 'Helios-Announcements');
+smalltalk.addClass('HLMethodsFocusRequested', globals.HLFocusRequested, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLPackagesFocusRequested', smalltalk.HLFocusRequested, [], 'Helios-Announcements');
+smalltalk.addClass('HLPackagesFocusRequested', globals.HLFocusRequested, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLProtocolsFocusRequested', smalltalk.HLFocusRequested, [], 'Helios-Announcements');
+smalltalk.addClass('HLProtocolsFocusRequested', globals.HLFocusRequested, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLSourceCodeFocusRequested', smalltalk.HLFocusRequested, [], 'Helios-Announcements');
+smalltalk.addClass('HLSourceCodeFocusRequested', globals.HLFocusRequested, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLInstVarAdded', smalltalk.HLAnnouncement, ['theClass', 'variableName'], 'Helios-Announcements');
+smalltalk.addClass('HLInstVarAdded', globals.HLAnnouncement, ['theClass', 'variableName'], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "theClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@theClass"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"theClass",{},smalltalk.HLInstVarAdded)})},
+},
 args: [],
 source: "theClass\x0a\x09^ theClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLInstVarAdded);
+globals.HLInstVarAdded);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "theClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@theClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass},smalltalk.HLInstVarAdded)})},
+return self},
 args: ["aClass"],
 source: "theClass: aClass\x0a\x09theClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLInstVarAdded);
+globals.HLInstVarAdded);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@variableName"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"variableName",{},smalltalk.HLInstVarAdded)})},
+},
 args: [],
 source: "variableName\x0a\x09^ variableName",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLInstVarAdded);
+globals.HLInstVarAdded);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "variableName:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@variableName"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"variableName:",{aString:aString},smalltalk.HLInstVarAdded)})},
+return self},
 args: ["aString"],
 source: "variableName: aString\x0a\x09variableName := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLInstVarAdded);
+globals.HLInstVarAdded);
 
 
 
-smalltalk.addClass('HLItemSelected', smalltalk.HLAnnouncement, ['item'], 'Helios-Announcements');
+smalltalk.addClass('HLItemSelected', globals.HLAnnouncement, ['item'], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "item",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@item"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"item",{},smalltalk.HLItemSelected)})},
+},
 args: [],
 source: "item\x0a\x09^ item",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLItemSelected);
+globals.HLItemSelected);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "item:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (anObject){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@item"]=anObject;
-return self}, function($ctx1) {$ctx1.fill(self,"item:",{anObject:anObject},smalltalk.HLItemSelected)})},
+return self},
 args: ["anObject"],
 source: "item: anObject\x0a\x09item := anObject",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLItemSelected);
+globals.HLItemSelected);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "on:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (anItem){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -506,76 +483,109 @@ _st($2)._item_(anItem);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{anItem:anItem},smalltalk.HLItemSelected.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:",{anItem:anItem},globals.HLItemSelected.klass)})},
 args: ["anItem"],
 source: "on: anItem\x0a\x09^ self new\x0a    \x09item: anItem;\x0a        yourself",
 messageSends: ["item:", "new", "yourself"],
 referencedClasses: []
 }),
-smalltalk.HLItemSelected.klass);
+globals.HLItemSelected.klass);
 
 
-smalltalk.addClass('HLClassSelected', smalltalk.HLItemSelected, [], 'Helios-Announcements');
+smalltalk.addClass('HLClassSelected', globals.HLItemSelected, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLInstanceVariableSelected', smalltalk.HLItemSelected, [], 'Helios-Announcements');
+smalltalk.addClass('HLInstanceVariableSelected', globals.HLItemSelected, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLMethodSelected', smalltalk.HLItemSelected, [], 'Helios-Announcements');
+smalltalk.addClass('HLMethodSelected', globals.HLItemSelected, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLPackageSelected', smalltalk.HLItemSelected, [], 'Helios-Announcements');
+smalltalk.addClass('HLPackageSelected', globals.HLItemSelected, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLProtocolSelected', smalltalk.HLItemSelected, [], 'Helios-Announcements');
+smalltalk.addClass('HLProtocolSelected', globals.HLItemSelected, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLSaveSourceCode', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLSaveSourceCode', globals.HLAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLSearchReferences', smalltalk.HLAnnouncement, ['searchString'], 'Helios-Announcements');
+smalltalk.addClass('HLSearchReferences', globals.HLAnnouncement, ['searchString'], 'Helios-Announcements');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "searchString",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@searchString"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"searchString",{},smalltalk.HLSearchReferences)})},
+},
 args: [],
 source: "searchString\x0a\x09^ searchString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSearchReferences);
+globals.HLSearchReferences);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "searchString:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@searchString"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"searchString:",{aString:aString},smalltalk.HLSearchReferences)})},
+return self},
 args: ["aString"],
 source: "searchString: aString\x0a\x09searchString := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSearchReferences);
+globals.HLSearchReferences);
+
+
 
+smalltalk.addClass('HLShowCommentToggled', globals.HLAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLShowCommentToggled', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLShowInstanceToggled', globals.HLAnnouncement, [], 'Helios-Announcements');
 
 
-smalltalk.addClass('HLShowInstanceToggled', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLShowTemplate', globals.HLAnnouncement, ['template'], 'Helios-Announcements');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "template",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@template"];
+return $1;
+},
+args: [],
+source: "template\x0a\x09^ template",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLShowTemplate);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "template:",
+protocol: 'accessing',
+fn: function (aString){
+var self=this;
+self["@template"]=aString;
+return self},
+args: ["aString"],
+source: "template: aString\x0a\x09template := aString",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLShowTemplate);
+
 
 
-smalltalk.addClass('HLSourceCodeSaved', smalltalk.HLAnnouncement, [], 'Helios-Announcements');
+smalltalk.addClass('HLSourceCodeSaved', globals.HLAnnouncement, [], 'Helios-Announcements');
 
 });

File diff suppressed because it is too large
+ 241 - 169
js/Helios-Browser.js


+ 342 - 139
js/Helios-Commands-Browser.js

@@ -1,593 +1,796 @@
-define("amber_core/Helios-Commands-Browser", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Helios-Commands-Tools"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Commands-Browser", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Helios-Commands-Tools"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Commands-Browser');
 smalltalk.packages["Helios-Commands-Browser"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLBrowserCommand', smalltalk.HLToolCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLBrowserCommand', globals.HLToolCommand, [], 'Helios-Commands-Browser');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isValidFor:",
-category: 'testing',
+protocol: 'testing',
 fn: function (aModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(aModel)._isBrowserModel();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},smalltalk.HLBrowserCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},globals.HLBrowserCommand.klass)})},
 args: ["aModel"],
 source: "isValidFor: aModel\x0a\x09^ aModel isBrowserModel",
 messageSends: ["isBrowserModel"],
 referencedClasses: []
 }),
-smalltalk.HLBrowserCommand.klass);
+globals.HLBrowserCommand.klass);
 
 
-smalltalk.addClass('HLBrowserGoToCommand', smalltalk.HLBrowserCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLBrowserGoToCommand', globals.HLBrowserCommand, [], 'Helios-Commands-Browser');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isValidFor:",
-category: 'testing',
+protocol: 'testing',
 fn: function (aModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(aModel)._isBrowserModel();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},smalltalk.HLBrowserGoToCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},globals.HLBrowserGoToCommand.klass)})},
 args: ["aModel"],
 source: "isValidFor: aModel\x0a\x09^ aModel isBrowserModel",
 messageSends: ["isBrowserModel"],
 referencedClasses: []
 }),
-smalltalk.HLBrowserGoToCommand.klass);
+globals.HLBrowserGoToCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "g";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLBrowserGoToCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'g'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLBrowserGoToCommand.klass);
+globals.HLBrowserGoToCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Go to";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLBrowserGoToCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Go to'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLBrowserGoToCommand.klass);
+globals.HLBrowserGoToCommand.klass);
 
 
-smalltalk.addClass('HLGoToClassesCommand', smalltalk.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLGoToClassesCommand', globals.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._focusOnClasses();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLGoToClassesCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLGoToClassesCommand)})},
 args: [],
 source: "execute\x0a\x09self model focusOnClasses",
 messageSends: ["focusOnClasses", "model"],
 referencedClasses: []
 }),
-smalltalk.HLGoToClassesCommand);
+globals.HLGoToClassesCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGoToClassesCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToClassesCommand.klass);
+globals.HLGoToClassesCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Classes";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGoToClassesCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Classes'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToClassesCommand.klass);
+globals.HLGoToClassesCommand.klass);
 
 
-smalltalk.addClass('HLGoToMethodsCommand', smalltalk.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLGoToMethodsCommand', globals.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._focusOnMethods();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLGoToMethodsCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLGoToMethodsCommand)})},
 args: [],
 source: "execute\x0a\x09self model focusOnMethods",
 messageSends: ["focusOnMethods", "model"],
 referencedClasses: []
 }),
-smalltalk.HLGoToMethodsCommand);
+globals.HLGoToMethodsCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "m";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGoToMethodsCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'm'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToMethodsCommand.klass);
+globals.HLGoToMethodsCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Methods";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGoToMethodsCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Methods'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToMethodsCommand.klass);
+globals.HLGoToMethodsCommand.klass);
 
 
-smalltalk.addClass('HLGoToPackagesCommand', smalltalk.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLGoToPackagesCommand', globals.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._focusOnPackages();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLGoToPackagesCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLGoToPackagesCommand)})},
 args: [],
 source: "execute\x0a\x09self model focusOnPackages",
 messageSends: ["focusOnPackages", "model"],
 referencedClasses: []
 }),
-smalltalk.HLGoToPackagesCommand);
+globals.HLGoToPackagesCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "p";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGoToPackagesCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'p'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToPackagesCommand.klass);
+globals.HLGoToPackagesCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Packages";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGoToPackagesCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Packages'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToPackagesCommand.klass);
+globals.HLGoToPackagesCommand.klass);
 
 
-smalltalk.addClass('HLGoToProtocolsCommand', smalltalk.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLGoToProtocolsCommand', globals.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._focusOnProtocols();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLGoToProtocolsCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLGoToProtocolsCommand)})},
 args: [],
 source: "execute\x0a\x09self model focusOnProtocols",
 messageSends: ["focusOnProtocols", "model"],
 referencedClasses: []
 }),
-smalltalk.HLGoToProtocolsCommand);
+globals.HLGoToProtocolsCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "t";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGoToProtocolsCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 't'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToProtocolsCommand.klass);
+globals.HLGoToProtocolsCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Protocols";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGoToProtocolsCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Protocols'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToProtocolsCommand.klass);
+globals.HLGoToProtocolsCommand.klass);
 
 
-smalltalk.addClass('HLGoToSourceCodeCommand', smalltalk.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLGoToSourceCodeCommand', globals.HLBrowserGoToCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._focusOnSourceCode();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLGoToSourceCodeCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLGoToSourceCodeCommand)})},
 args: [],
 source: "execute\x0a\x09self model focusOnSourceCode",
 messageSends: ["focusOnSourceCode", "model"],
 referencedClasses: []
 }),
-smalltalk.HLGoToSourceCodeCommand);
+globals.HLGoToSourceCodeCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "s";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLGoToSourceCodeCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 's'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToSourceCodeCommand.klass);
+globals.HLGoToSourceCodeCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Source code";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLGoToSourceCodeCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Source code'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLGoToSourceCodeCommand.klass);
+globals.HLGoToSourceCodeCommand.klass);
 
 
-smalltalk.addClass('HLEditCommentCommand', smalltalk.HLBrowserCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLEditCommentCommand', globals.HLBrowserCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._editComment();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLEditCommentCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLEditCommentCommand)})},
 args: [],
 source: "execute\x0a\x09self model editComment",
 messageSends: ["editComment", "model"],
 referencedClasses: []
 }),
-smalltalk.HLEditCommentCommand);
+globals.HLEditCommentCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(self._model())._showComment())._and_((function(){
+var $3,$2,$1;
+$3=self._model();
+$ctx1.sendIdx["model"]=1;
+$2=_st($3)._showComment();
+$1=_st($2)._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(self._model())._selectedClass())._notNil();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLEditCommentCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLEditCommentCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model showComment and: [ self model selectedClass notNil ]",
 messageSends: ["and:", "showComment", "model", "notNil", "selectedClass"],
 referencedClasses: []
 }),
-smalltalk.HLEditCommentCommand);
+globals.HLEditCommentCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "d";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLEditCommentCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'd'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLEditCommentCommand.klass);
+globals.HLEditCommentCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Edit documentation";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLEditCommentCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Edit documentation'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLEditCommentCommand.klass);
+globals.HLEditCommentCommand.klass);
+
+
+smalltalk.addClass('HLGenerateCommand', globals.HLBrowserCommand, [], 'Helios-Commands-Browser');
+globals.HLGenerateCommand.comment="I am a group command used to gather all the commands generating code (`accessors`, `initialize`, etc)";
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "h";
+},
+args: [],
+source: "key\x0a\x09^ 'h'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerateCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "Generate";
+},
+args: [],
+source: "label\x0a\x09^ 'Generate'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerateCommand.klass);
+
+
+smalltalk.addClass('HLCategorizeUnclassifiedCommand', globals.HLGenerateCommand, [], 'Helios-Commands-Browser');
+globals.HLCategorizeUnclassifiedCommand.comment="I am the command used to categorize unclassified methods";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "execute",
+protocol: 'executing',
+fn: function (){
+var self=this;
+var targetClass,unclassified;
+function $HLMethodClassifier(){return globals.HLMethodClassifier||(typeof HLMethodClassifier=="undefined"?nil:HLMethodClassifier)}
+return smalltalk.withContext(function($ctx1) { 
+targetClass=_st(self._model())._selectedClass();
+unclassified=_st(_st(targetClass)._methods())._select_((function(e){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(e)._protocol()).__eq("as yet unclassified");
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1,1)})}));
+_st(_st($HLMethodClassifier())._new())._classifyAll_(unclassified);
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{targetClass:targetClass,unclassified:unclassified},globals.HLCategorizeUnclassifiedCommand)})},
+args: [],
+source: "execute\x0a\x09| targetClass unclassified |\x0a\x09targetClass := self model selectedClass.\x0a\x0a\x09unclassified := targetClass methods select:[ :e | e protocol = 'as yet unclassified' ].\x0a\x09\x09\x0a\x09HLMethodClassifier new\x0a\x09\x09classifyAll: unclassified",
+messageSends: ["selectedClass", "model", "select:", "methods", "=", "protocol", "classifyAll:", "new"],
+referencedClasses: ["HLMethodClassifier"]
+}),
+globals.HLCategorizeUnclassifiedCommand);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "c";
+},
+args: [],
+source: "key\x0a\x09^ 'c'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLCategorizeUnclassifiedCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "Categorize";
+},
+args: [],
+source: "label\x0a\x09^ 'Categorize'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLCategorizeUnclassifiedCommand.klass);
 
 
-smalltalk.addClass('HLToggleCommand', smalltalk.HLBrowserCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLGenerateAccessorsCommand', globals.HLGenerateCommand, [], 'Helios-Commands-Browser');
+globals.HLGenerateAccessorsCommand.comment="I am the command used to generate the `getter` and the `setter` methods depending of the selected class";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "execute",
+protocol: 'executing',
+fn: function (){
+var self=this;
+var targetClass,output,first;
+function $HLInitializeGenerator(){return globals.HLInitializeGenerator||(typeof HLInitializeGenerator=="undefined"?nil:HLInitializeGenerator)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3,$4,$5;
+$1=self._model();
+$ctx1.sendIdx["model"]=1;
+targetClass=_st($1)._selectedClass();
+$2=_st($HLInitializeGenerator())._new();
+_st($2)._class_(targetClass);
+_st($2)._generate();
+$3=_st($2)._output();
+output=$3;
+_st(output)._compile();
+first=_st(_st(output)._sourceCodes())._first();
+$4=self._model();
+_st($4)._selectedProtocol_(_st(output)._protocol());
+_st($4)._selectedMethod_(_st(targetClass).__gt_gt(_st(first)._selector()));
+$5=_st($4)._focusOnSourceCode();
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{targetClass:targetClass,output:output,first:first},globals.HLGenerateAccessorsCommand)})},
+args: [],
+source: "execute\x0a\x09| targetClass output first |\x0a\x09targetClass := self model selectedClass.\x0a\x0a\x09output := HLInitializeGenerator new\x0a\x09\x09class: targetClass;\x0a\x09\x09generate;\x0a\x09\x09output.\x0a\x09\x09\x0a\x09output compile.\x0a\x09first := output sourceCodes first.\x0a\x09self model\x0a\x09\x09selectedProtocol: output protocol;\x0a\x09\x09selectedMethod:(targetClass>>first selector);\x0a\x09\x09focusOnSourceCode",
+messageSends: ["selectedClass", "model", "class:", "new", "generate", "output", "compile", "first", "sourceCodes", "selectedProtocol:", "protocol", "selectedMethod:", ">>", "selector", "focusOnSourceCode"],
+referencedClasses: ["HLInitializeGenerator"]
+}),
+globals.HLGenerateAccessorsCommand);
+
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "i";
+},
+args: [],
+source: "key\x0a\x09^ 'i'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerateAccessorsCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "Initialize";
+},
+args: [],
+source: "label\x0a\x09^ 'Initialize'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerateAccessorsCommand.klass);
+
+
+smalltalk.addClass('HLGenerateInitializeCommand', globals.HLGenerateCommand, [], 'Helios-Commands-Browser');
+globals.HLGenerateInitializeCommand.comment="I am the command used to generate the `initialize` method depending of the selected class";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "execute",
+protocol: 'executing',
 fn: function (){
 var self=this;
+var targetClass,output;
+function $HLAccessorsGenerator(){return globals.HLAccessorsGenerator||(typeof HLAccessorsGenerator=="undefined"?nil:HLAccessorsGenerator)}
 return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
+$1=self._model();
+$ctx1.sendIdx["model"]=1;
+targetClass=_st($1)._selectedClass();
+$2=_st($HLAccessorsGenerator())._new();
+_st($2)._class_(targetClass);
+_st($2)._generate();
+$3=_st($2)._output();
+output=$3;
+_st(output)._compile();
+_st(self._model())._selectedProtocol_(_st(output)._protocol());
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{targetClass:targetClass,output:output},globals.HLGenerateInitializeCommand)})},
+args: [],
+source: "execute\x0a\x09| targetClass output |\x0a\x09targetClass := self model selectedClass.\x0a\x0a\x09output := HLAccessorsGenerator new\x0a\x09\x09class: targetClass;\x0a\x09\x09generate;\x0a\x09\x09output.\x0a\x09\x09\x0a\x09output compile.\x0a\x09self model selectedProtocol: output protocol",
+messageSends: ["selectedClass", "model", "class:", "new", "generate", "output", "compile", "selectedProtocol:", "protocol"],
+referencedClasses: ["HLAccessorsGenerator"]
+}),
+globals.HLGenerateInitializeCommand);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "a";
+},
+args: [],
+source: "key\x0a\x09^ 'a'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerateInitializeCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "Accessors";
+},
+args: [],
+source: "label\x0a\x09^ 'Accessors'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerateInitializeCommand.klass);
+
+
+smalltalk.addClass('HLToggleCommand', globals.HLBrowserCommand, [], 'Helios-Commands-Browser');
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
 return "t";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLToggleCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 't'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleCommand.klass);
+globals.HLToggleCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Toggle";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLToggleCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Toggle'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleCommand.klass);
+globals.HLToggleCommand.klass);
 
 
-smalltalk.addClass('HLToggleClassCommentCommand', smalltalk.HLToggleCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLToggleClassCommentCommand', globals.HLToggleCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self._model())._showComment_(_st(_st(self._model())._showComment())._not());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLToggleClassCommentCommand)})},
+var $1;
+$1=self._model();
+$ctx1.sendIdx["model"]=1;
+_st($1)._showComment_(_st(_st(self._model())._showComment())._not());
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLToggleClassCommentCommand)})},
 args: [],
 source: "execute\x0a\x09self model showComment: self model showComment not",
 messageSends: ["showComment:", "model", "not", "showComment"],
 referencedClasses: []
 }),
-smalltalk.HLToggleClassCommentCommand);
+globals.HLToggleClassCommentCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "d";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLToggleClassCommentCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'd'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleClassCommentCommand.klass);
+globals.HLToggleClassCommentCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Documentation";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLToggleClassCommentCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Documentation'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleClassCommentCommand.klass);
+globals.HLToggleClassCommentCommand.klass);
 
 
-smalltalk.addClass('HLToggleClassSideCommand', smalltalk.HLToggleCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLToggleClassSideCommand', globals.HLToggleCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._showInstance_(false);
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLToggleClassSideCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLToggleClassSideCommand)})},
 args: [],
 source: "execute\x0a\x09self model showInstance: false",
 messageSends: ["showInstance:", "model"],
 referencedClasses: []
 }),
-smalltalk.HLToggleClassSideCommand);
+globals.HLToggleClassSideCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLToggleClassSideCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleClassSideCommand.klass);
+globals.HLToggleClassSideCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Class side";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLToggleClassSideCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Class side'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleClassSideCommand.klass);
+globals.HLToggleClassSideCommand.klass);
 
 
-smalltalk.addClass('HLToggleInstanceSideCommand', smalltalk.HLToggleCommand, [], 'Helios-Commands-Browser');
+smalltalk.addClass('HLToggleInstanceSideCommand', globals.HLToggleCommand, [], 'Helios-Commands-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._showInstance_(true);
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLToggleInstanceSideCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLToggleInstanceSideCommand)})},
 args: [],
 source: "execute\x0a\x09self model showInstance: true",
 messageSends: ["showInstance:", "model"],
 referencedClasses: []
 }),
-smalltalk.HLToggleInstanceSideCommand);
+globals.HLToggleInstanceSideCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "i";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLToggleInstanceSideCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'i'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleInstanceSideCommand.klass);
+globals.HLToggleInstanceSideCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Instance side";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLToggleInstanceSideCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Instance side'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToggleInstanceSideCommand.klass);
+globals.HLToggleInstanceSideCommand.klass);
 
 });

+ 175 - 197
js/Helios-Commands-Core.js

@@ -1,15 +1,15 @@
-define("amber_core/Helios-Commands-Core", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Commands-Core", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Commands-Core');
 smalltalk.packages["Helios-Commands-Core"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLCommand', smalltalk.Object, ['input'], 'Helios-Commands-Core');
+smalltalk.addClass('HLCommand', globals.Object, ['input'], 'Helios-Commands-Core');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "asActionBinding",
-category: 'converting',
+protocol: 'converting',
 fn: function (){
 var self=this;
-function $HLBindingAction(){return smalltalk.HLBindingAction||(typeof HLBindingAction=="undefined"?nil:HLBindingAction)}
+function $HLBindingAction(){return globals.HLBindingAction||(typeof HLBindingAction=="undefined"?nil:HLBindingAction)}
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
 $2=_st($HLBindingAction())._on_labelled_(self._keyCode(),self._label());
@@ -17,18 +17,18 @@ _st($2)._command_(self);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"asActionBinding",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"asActionBinding",{},globals.HLCommand)})},
 args: [],
 source: "asActionBinding\x0a\x09^ (HLBindingAction on: self keyCode labelled: self label)\x0a    \x09command: self;\x0a\x09\x09yourself",
 messageSends: ["command:", "on:labelled:", "keyCode", "label", "yourself"],
 referencedClasses: ["HLBindingAction"]
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "asBinding",
-category: 'converting',
+protocol: 'converting',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -40,338 +40,331 @@ $1=self._asGroupBinding();
 $1=self._asActionBinding();
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"asBinding",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"asBinding",{},globals.HLCommand)})},
 args: [],
 source: "asBinding\x0a\x09^ self isBindingGroup\x0a\x09\x09ifTrue: [ self asGroupBinding ]\x0a\x09\x09ifFalse: [ self asActionBinding ]",
 messageSends: ["ifTrue:ifFalse:", "isBindingGroup", "asGroupBinding", "asActionBinding"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "asGroupBinding",
-category: 'converting',
+protocol: 'converting',
 fn: function (){
 var self=this;
-function $HLBindingGroup(){return smalltalk.HLBindingGroup||(typeof HLBindingGroup=="undefined"?nil:HLBindingGroup)}
+function $HLBindingGroup(){return globals.HLBindingGroup||(typeof HLBindingGroup=="undefined"?nil:HLBindingGroup)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st($HLBindingGroup())._on_labelled_(self._keyCode(),self._label());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"asGroupBinding",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"asGroupBinding",{},globals.HLCommand)})},
 args: [],
 source: "asGroupBinding\x0a\x09^ HLBindingGroup \x0a\x09\x09on: self keyCode\x0a\x09\x09labelled: self label",
 messageSends: ["on:labelled:", "keyCode", "label"],
 referencedClasses: ["HLBindingGroup"]
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "commandError:",
-category: 'error handling',
+protocol: 'error handling',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._error_(aString);
-return self}, function($ctx1) {$ctx1.fill(self,"commandError:",{aString:aString},smalltalk.HLCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"commandError:",{aString:aString},globals.HLCommand)})},
 args: ["aString"],
 source: "commandError: aString\x0a\x09self error: aString",
 messageSends: ["error:"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultInput",
-category: 'defaults',
+protocol: 'defaults',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "";
-}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},smalltalk.HLCommand)})},
+},
 args: [],
 source: "defaultInput\x0a\x09^ ''",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "documentation",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._class())._documentation();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"documentation",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"documentation",{},globals.HLCommand)})},
 args: [],
 source: "documentation\x0a\x09^ self class documentation",
 messageSends: ["documentation", "class"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLCommand)})},
+return self},
 args: [],
 source: "execute",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "input",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@input"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"input",{},smalltalk.HLCommand)})},
+},
 args: [],
 source: "input\x0a\x09^ input",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "input:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 self["@input"]=aString;
 $1=self["@input"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"input:",{aString:aString},smalltalk.HLCommand)})},
+},
 args: ["aString"],
 source: "input: aString\x0a\x09^ input := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputCompletion",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=[];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},smalltalk.HLCommand)})},
+},
 args: [],
 source: "inputCompletion\x0a\x09^ #()",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._label();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"inputLabel",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"inputLabel",{},globals.HLCommand)})},
 args: [],
 source: "inputLabel\x0a\x09^ self label",
 messageSends: ["label"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isAction",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._isBindingGroup())._not();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isAction",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isAction",{},globals.HLCommand)})},
 args: [],
 source: "isAction\x0a\x09^ self isBindingGroup not",
 messageSends: ["not", "isBindingGroup"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLCommand)})},
+},
 args: [],
 source: "isActive\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isBindingGroup",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(_st(self._class())._methodDictionary())._includesKey_("execute"))._not();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isBindingGroup",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isBindingGroup",{},globals.HLCommand)})},
 args: [],
 source: "isBindingGroup\x0a\x09^ (self class methodDictionary includesKey: 'execute') not",
 messageSends: ["not", "includesKey:", "methodDictionary", "class"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return false;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ false",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._class())._key();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"key",{},globals.HLCommand)})},
 args: [],
 source: "key\x0a\x09^ self class key",
 messageSends: ["key", "class"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "keyCode",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._key())._asUppercase())._charCodeAt_((1));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"keyCode",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"keyCode",{},globals.HLCommand)})},
 args: [],
 source: "keyCode\x0a\x09^ self key asUppercase charCodeAt: 1",
 messageSends: ["charCodeAt:", "asUppercase", "key"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._class())._label();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"label",{},globals.HLCommand)})},
 args: [],
 source: "label\x0a\x09^ self class label",
 messageSends: ["label", "class"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._class())._menuLabel();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},globals.HLCommand)})},
 args: [],
 source: "menuLabel\x0a\x09^ self class menuLabel",
 messageSends: ["menuLabel", "class"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "registerOn:",
-category: 'registration',
+protocol: 'registration',
 fn: function (aBinding){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(aBinding)._add_(self._asBinding());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"registerOn:",{aBinding:aBinding},smalltalk.HLCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"registerOn:",{aBinding:aBinding},globals.HLCommand)})},
 args: ["aBinding"],
 source: "registerOn: aBinding\x0a\x09^ aBinding add: self asBinding",
 messageSends: ["add:", "asBinding"],
 referencedClasses: []
 }),
-smalltalk.HLCommand);
+globals.HLCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "concreteClasses",
-category: 'registration',
+protocol: 'registration',
 fn: function (){
 var self=this;
 var classes;
-function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+function $OrderedCollection(){return globals.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 classes=_st($OrderedCollection())._new();
@@ -385,118 +378,114 @@ return _st(classes)._addAll_(_st(each)._concreteClasses());
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,2)})}));
 $2=classes;
 return $2;
-}, function($ctx1) {$ctx1.fill(self,"concreteClasses",{classes:classes},smalltalk.HLCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"concreteClasses",{classes:classes},globals.HLCommand.klass)})},
 args: [],
 source: "concreteClasses\x0a\x09| classes |\x0a\x09\x0a\x09classes := OrderedCollection new.\x0a\x09\x0a\x09self isConcrete\x0a\x09\x09ifTrue: [ classes add: self ].\x0a\x09\x09\x0a\x09self subclasses do: [ :each | \x0a\x09\x09classes addAll: each concreteClasses ].\x0a\x09\x09\x0a\x09^ classes",
 messageSends: ["new", "ifTrue:", "isConcrete", "add:", "do:", "subclasses", "addAll:", "concreteClasses"],
 referencedClasses: ["OrderedCollection"]
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "documentation",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "";
-}, function($ctx1) {$ctx1.fill(self,"documentation",{},smalltalk.HLCommand.klass)})},
+},
 args: [],
 source: "documentation\x0a\x09^ ''",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isConcrete",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._key())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isConcrete",{},smalltalk.HLCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"isConcrete",{},globals.HLCommand.klass)})},
 args: [],
 source: "isConcrete\x0a\x09^ self key notNil",
 messageSends: ["notNil", "key"],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isValidFor:",
-category: 'testing',
+protocol: 'testing',
 fn: function (aModel){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},smalltalk.HLCommand.klass)})},
+},
 args: ["aModel"],
 source: "isValidFor: aModel\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return nil;
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09\x22Answer a single character string or nil if no key\x22\x0a\x09\x0a\x09^ nil",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ ''",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._label();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},globals.HLCommand.klass)})},
 args: [],
 source: "menuLabel\x0a\x09^ self label",
 messageSends: ["label"],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "registerConcreteClassesOn:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aBinding){
 var self=this;
 var newBinding;
@@ -514,143 +503,139 @@ _st(self._subclasses())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._registerConcreteClassesOn_(newBinding);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,3)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"registerConcreteClassesOn:",{aBinding:aBinding,newBinding:newBinding},smalltalk.HLCommand.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"registerConcreteClassesOn:",{aBinding:aBinding,newBinding:newBinding},globals.HLCommand.klass)})},
 args: ["aBinding"],
 source: "registerConcreteClassesOn: aBinding\x0a\x09| newBinding |\x0a\x09\x0a\x09self isConcrete\x0a\x09\x09ifTrue: [ newBinding := self registerOn: aBinding ]\x0a\x09\x09ifFalse: [ newBinding := aBinding ].\x0a\x09\x09\x0a\x09self subclasses do: [ :each | each registerConcreteClassesOn: newBinding ]",
 messageSends: ["ifTrue:ifFalse:", "isConcrete", "registerOn:", "do:", "subclasses", "registerConcreteClassesOn:"],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "registerOn:",
-category: 'registration',
+protocol: 'registration',
 fn: function (aBinding){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._new())._registerOn_(aBinding);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"registerOn:",{aBinding:aBinding},smalltalk.HLCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"registerOn:",{aBinding:aBinding},globals.HLCommand.klass)})},
 args: ["aBinding"],
 source: "registerOn: aBinding\x0a\x09^ self new registerOn: aBinding",
 messageSends: ["registerOn:", "new"],
 referencedClasses: []
 }),
-smalltalk.HLCommand.klass);
+globals.HLCommand.klass);
 
 
-smalltalk.addClass('HLCloseTabCommand', smalltalk.HLCommand, [], 'Helios-Commands-Core');
+smalltalk.addClass('HLCloseTabCommand', globals.HLCommand, [], 'Helios-Commands-Core');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
-function $HLManager(){return smalltalk.HLManager||(typeof HLManager=="undefined"?nil:HLManager)}
+function $HLManager(){return globals.HLManager||(typeof HLManager=="undefined"?nil:HLManager)}
 return smalltalk.withContext(function($ctx1) { 
 _st(_st($HLManager())._current())._removeActiveTab();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLCloseTabCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLCloseTabCommand)})},
 args: [],
 source: "execute\x0a\x09HLManager current removeActiveTab",
 messageSends: ["removeActiveTab", "current"],
 referencedClasses: ["HLManager"]
 }),
-smalltalk.HLCloseTabCommand);
+globals.HLCloseTabCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "w";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLCloseTabCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'w'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCloseTabCommand.klass);
+globals.HLCloseTabCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Close tab";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLCloseTabCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Close tab'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCloseTabCommand.klass);
+globals.HLCloseTabCommand.klass);
 
 
-smalltalk.addClass('HLModelCommand', smalltalk.HLCommand, ['model'], 'Helios-Commands-Core');
+smalltalk.addClass('HLModelCommand', globals.HLCommand, ['model'], 'Helios-Commands-Core');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "model",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@model"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"model",{},smalltalk.HLModelCommand)})},
+},
 args: [],
 source: "model\x0a\x09^ model",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLModelCommand);
+globals.HLModelCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "model:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aModel){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@model"]=aModel;
-return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel},smalltalk.HLModelCommand)})},
+return self},
 args: ["aModel"],
 source: "model: aModel\x0a\x09model := aModel",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLModelCommand);
+globals.HLModelCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "for:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (aModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self._new();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"for:",{aModel:aModel},smalltalk.HLModelCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"for:",{aModel:aModel},globals.HLModelCommand.klass)})},
 args: ["aModel"],
 source: "for: aModel\x0a\x09^ self new",
 messageSends: ["new"],
 referencedClasses: []
 }),
-smalltalk.HLModelCommand.klass);
+globals.HLModelCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "registerConcreteClassesOn:for:",
-category: 'registration',
+protocol: 'registration',
 fn: function (aBinding,aModel){
 var self=this;
 var newBinding;
@@ -671,194 +656,190 @@ _st(self._subclasses())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._registerConcreteClassesOn_for_(newBinding,aModel);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,4)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"registerConcreteClassesOn:for:",{aBinding:aBinding,aModel:aModel,newBinding:newBinding},smalltalk.HLModelCommand.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"registerConcreteClassesOn:for:",{aBinding:aBinding,aModel:aModel,newBinding:newBinding},globals.HLModelCommand.klass)})},
 args: ["aBinding", "aModel"],
 source: "registerConcreteClassesOn: aBinding for: aModel\x0a\x09| newBinding |\x0a\x09\x0a\x09(self isConcrete and: [ self isValidFor: aModel ])\x0a\x09\x09ifTrue: [ newBinding := self registerOn: aBinding for: aModel ]\x0a\x09\x09ifFalse: [ newBinding := aBinding ].\x0a\x09\x09\x0a\x09self subclasses do: [ :each |\x0a\x09\x09each registerConcreteClassesOn: newBinding for: aModel ]",
 messageSends: ["ifTrue:ifFalse:", "and:", "isConcrete", "isValidFor:", "registerOn:for:", "do:", "subclasses", "registerConcreteClassesOn:for:"],
 referencedClasses: []
 }),
-smalltalk.HLModelCommand.klass);
+globals.HLModelCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "registerOn:for:",
-category: 'registration',
+protocol: 'registration',
 fn: function (aBinding,aModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._for_(aModel))._registerOn_(aBinding);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"registerOn:for:",{aBinding:aBinding,aModel:aModel},smalltalk.HLModelCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"registerOn:for:",{aBinding:aBinding,aModel:aModel},globals.HLModelCommand.klass)})},
 args: ["aBinding", "aModel"],
 source: "registerOn: aBinding for: aModel\x0a\x09^ (self for: aModel) registerOn: aBinding",
 messageSends: ["registerOn:", "for:"],
 referencedClasses: []
 }),
-smalltalk.HLModelCommand.klass);
+globals.HLModelCommand.klass);
 
 
-smalltalk.addClass('HLOpenCommand', smalltalk.HLCommand, [], 'Helios-Commands-Core');
+smalltalk.addClass('HLOpenCommand', globals.HLCommand, [], 'Helios-Commands-Core');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "o";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLOpenCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'o'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLOpenCommand.klass);
+globals.HLOpenCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Open";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLOpenCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Open'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLOpenCommand.klass);
+globals.HLOpenCommand.klass);
 
 
-smalltalk.addClass('HLOpenBrowserCommand', smalltalk.HLOpenCommand, [], 'Helios-Commands-Core');
+smalltalk.addClass('HLOpenBrowserCommand', globals.HLOpenCommand, [], 'Helios-Commands-Core');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
-function $HLBrowser(){return smalltalk.HLBrowser||(typeof HLBrowser=="undefined"?nil:HLBrowser)}
+function $HLBrowser(){return globals.HLBrowser||(typeof HLBrowser=="undefined"?nil:HLBrowser)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st($HLBrowser())._openAsTab();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLOpenBrowserCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLOpenBrowserCommand)})},
 args: [],
 source: "execute\x0a\x09^ HLBrowser openAsTab",
 messageSends: ["openAsTab"],
 referencedClasses: ["HLBrowser"]
 }),
-smalltalk.HLOpenBrowserCommand);
+globals.HLOpenBrowserCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "b";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLOpenBrowserCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'b'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLOpenBrowserCommand.klass);
+globals.HLOpenBrowserCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Browser";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLOpenBrowserCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Browser'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLOpenBrowserCommand.klass);
+globals.HLOpenBrowserCommand.klass);
 
 
-smalltalk.addClass('HLOpenWorkspaceCommand', smalltalk.HLOpenCommand, [], 'Helios-Commands-Core');
+smalltalk.addClass('HLOpenWorkspaceCommand', globals.HLOpenCommand, [], 'Helios-Commands-Core');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
-function $HLWorkspace(){return smalltalk.HLWorkspace||(typeof HLWorkspace=="undefined"?nil:HLWorkspace)}
+function $HLWorkspace(){return globals.HLWorkspace||(typeof HLWorkspace=="undefined"?nil:HLWorkspace)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st($HLWorkspace())._openAsTab();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLOpenWorkspaceCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLOpenWorkspaceCommand)})},
 args: [],
 source: "execute\x0a\x09^ HLWorkspace openAsTab",
 messageSends: ["openAsTab"],
 referencedClasses: ["HLWorkspace"]
 }),
-smalltalk.HLOpenWorkspaceCommand);
+globals.HLOpenWorkspaceCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "w";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLOpenWorkspaceCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'w'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLOpenWorkspaceCommand.klass);
+globals.HLOpenWorkspaceCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Workspace";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLOpenWorkspaceCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Workspace'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLOpenWorkspaceCommand.klass);
+globals.HLOpenWorkspaceCommand.klass);
 
 
-smalltalk.addClass('HLSwitchTabCommand', smalltalk.HLCommand, [], 'Helios-Commands-Core');
+smalltalk.addClass('HLSwitchTabCommand', globals.HLCommand, [], 'Helios-Commands-Core');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 var activeTab;
-function $HLTabSelectionWidget(){return smalltalk.HLTabSelectionWidget||(typeof HLTabSelectionWidget=="undefined"?nil:HLTabSelectionWidget)}
+function $HLTabSelectionWidget(){return globals.HLTabSelectionWidget||(typeof HLTabSelectionWidget=="undefined"?nil:HLTabSelectionWidget)}
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$1;
 activeTab=self._selectedTab();
+$ctx1.sendIdx["selectedTab"]=1;
 $2=_st($HLTabSelectionWidget())._new();
 _st($2)._tabs_(self._tabs());
 _st($2)._selectedTab_(self._selectedTab());
 _st($2)._selectCallback_((function(tab){
 return smalltalk.withContext(function($ctx2) {
 return _st(tab)._activate();
+$ctx2.sendIdx["activate"]=1;
 }, function($ctx2) {$ctx2.fillBlock({tab:tab},$ctx1,1)})}));
 _st($2)._confirmCallback_((function(tab){
 return smalltalk.withContext(function($ctx2) {
@@ -871,102 +852,99 @@ return _st(activeTab)._activate();
 $3=_st($2)._show();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"execute",{activeTab:activeTab},smalltalk.HLSwitchTabCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"execute",{activeTab:activeTab},globals.HLSwitchTabCommand)})},
 args: [],
 source: "execute\x0a\x09| activeTab |\x0a\x09\x0a\x09activeTab := self selectedTab.\x0a\x09\x0a\x09^ HLTabSelectionWidget new\x0a\x09\x09tabs: self tabs;\x0a\x09\x09selectedTab: self selectedTab;\x0a\x09\x09selectCallback: [ :tab | tab activate ];\x0a\x09\x09confirmCallback: [ :tab | tab focus ];\x0a\x09\x09cancelCallback: [ activeTab activate ];\x0a\x09\x09show",
 messageSends: ["selectedTab", "tabs:", "new", "tabs", "selectedTab:", "selectCallback:", "activate", "confirmCallback:", "focus", "cancelCallback:", "show"],
 referencedClasses: ["HLTabSelectionWidget"]
 }),
-smalltalk.HLSwitchTabCommand);
+globals.HLSwitchTabCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "selectedTab",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-function $HLManager(){return smalltalk.HLManager||(typeof HLManager=="undefined"?nil:HLManager)}
+function $HLManager(){return globals.HLManager||(typeof HLManager=="undefined"?nil:HLManager)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st($HLManager())._current())._activeTab();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectedTab",{},smalltalk.HLSwitchTabCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"selectedTab",{},globals.HLSwitchTabCommand)})},
 args: [],
 source: "selectedTab\x0a\x09^ HLManager current activeTab",
 messageSends: ["activeTab", "current"],
 referencedClasses: ["HLManager"]
 }),
-smalltalk.HLSwitchTabCommand);
+globals.HLSwitchTabCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "tabs",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-function $HLManager(){return smalltalk.HLManager||(typeof HLManager=="undefined"?nil:HLManager)}
+function $HLManager(){return globals.HLManager||(typeof HLManager=="undefined"?nil:HLManager)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st($HLManager())._current())._tabs();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"tabs",{},smalltalk.HLSwitchTabCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"tabs",{},globals.HLSwitchTabCommand)})},
 args: [],
 source: "tabs\x0a\x09^ HLManager current tabs",
 messageSends: ["tabs", "current"],
 referencedClasses: ["HLManager"]
 }),
-smalltalk.HLSwitchTabCommand);
+globals.HLSwitchTabCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "s";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLSwitchTabCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 's'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSwitchTabCommand.klass);
+globals.HLSwitchTabCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Switch";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLSwitchTabCommand.klass)})},
+return "Switch tab";
+},
 args: [],
-source: "label\x0a\x09^ 'Switch'",
+source: "label\x0a\x09^ 'Switch tab'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSwitchTabCommand.klass);
+globals.HLSwitchTabCommand.klass);
 
 
-smalltalk.addClass('HLViewCommand', smalltalk.HLCommand, [], 'Helios-Commands-Core');
+smalltalk.addClass('HLViewCommand', globals.HLCommand, [], 'Helios-Commands-Core');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "View";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLViewCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'View'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLViewCommand.klass);
+globals.HLViewCommand.klass);
 
 });

+ 485 - 480
js/Helios-Commands-Tools.js

@@ -1,29 +1,28 @@
-define("amber_core/Helios-Commands-Tools", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Helios-Commands-Core"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Commands-Tools", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Helios-Commands-Core"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Commands-Tools');
 smalltalk.packages["Helios-Commands-Tools"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLToolCommand', smalltalk.HLModelCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLToolCommand', globals.HLModelCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return nil;
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLToolCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ nil",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLToolCommand);
+globals.HLToolCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "for:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (aToolModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -33,490 +32,552 @@ _st($2)._model_(aToolModel);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"for:",{aToolModel:aToolModel},smalltalk.HLToolCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"for:",{aToolModel:aToolModel},globals.HLToolCommand.klass)})},
 args: ["aToolModel"],
 source: "for: aToolModel\x0a\x09^ self new\x0a    \x09model: aToolModel;\x0a        yourself",
 messageSends: ["model:", "new", "yourself"],
 referencedClasses: []
 }),
-smalltalk.HLToolCommand.klass);
+globals.HLToolCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isValidFor:",
-category: 'testing',
+protocol: 'testing',
 fn: function (aModel){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(aModel)._isToolModel();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},smalltalk.HLToolCommand.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},globals.HLToolCommand.klass)})},
 args: ["aModel"],
 source: "isValidFor: aModel\x0a\x09^ aModel isToolModel",
 messageSends: ["isToolModel"],
 referencedClasses: []
 }),
-smalltalk.HLToolCommand.klass);
+globals.HLToolCommand.klass);
 
 
-smalltalk.addClass('HLCommitPackageCommand', smalltalk.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLBrowseMethodCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
-selector: "category",
-category: 'accessing',
+selector: "displayLabel",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "browse method";
+},
+args: [],
+source: "displayLabel\x0a\x09^ 'browse method'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "execute",
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+_st(self._model())._openMethod();
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLBrowseMethodCommand)})},
+args: [],
+source: "execute\x0a\x09self model openMethod",
+messageSends: ["openMethod", "model"],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isValidFor:",
+protocol: 'testing',
+fn: function (aModel){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(aModel)._isReferencesModel();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},globals.HLBrowseMethodCommand.klass)})},
+args: ["aModel"],
+source: "isValidFor: aModel\x0a\x09^ aModel isReferencesModel",
+messageSends: ["isReferencesModel"],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "key",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "b";
+},
+args: [],
+source: "key\x0a\x09^ 'b'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "label",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+return "browse method";
+},
+args: [],
+source: "label\x0a\x09^ 'browse method'",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLBrowseMethodCommand.klass);
+
+
+smalltalk.addClass('HLCommitPackageCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "category",
+protocol: 'accessing',
+fn: function (){
+var self=this;
 return "Packages";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLCommitPackageCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Packages'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommitPackageCommand);
+globals.HLCommitPackageCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._commitPackage();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLCommitPackageCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLCommitPackageCommand)})},
 args: [],
 source: "execute\x0a\x09self model commitPackage",
 messageSends: ["commitPackage", "model"],
 referencedClasses: []
 }),
-smalltalk.HLCommitPackageCommand);
+globals.HLCommitPackageCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLCommitPackageCommand)})},
+},
 args: [],
 source: "isActive\x0a\x09^ true\x0a\x09\x22 slf model isPackageDirty\x22",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommitPackageCommand);
+globals.HLCommitPackageCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "k";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLCommitPackageCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'k'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommitPackageCommand.klass);
+globals.HLCommitPackageCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Commit";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLCommitPackageCommand.klass)})},
+return "Commit package";
+},
 args: [],
-source: "label\x0a\x09^ 'Commit'",
+source: "label\x0a\x09^ 'Commit package'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCommitPackageCommand.klass);
+globals.HLCommitPackageCommand.klass);
 
 
-smalltalk.addClass('HLCopyCommand', smalltalk.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLCopyCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLCopyCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyCommand.klass);
+globals.HLCopyCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Copy";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLCopyCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Copy'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyCommand.klass);
+globals.HLCopyCommand.klass);
 
 
-smalltalk.addClass('HLCopyClassCommand', smalltalk.HLCopyCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLCopyClassCommand', globals.HLCopyCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Classes";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLCopyClassCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Classes'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand);
+globals.HLCopyClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultInput",
-category: 'defaults',
+protocol: 'defaults',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedClass())._name();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},smalltalk.HLCopyClassCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},globals.HLCopyClassCommand)})},
 args: [],
 source: "defaultInput\x0a\x09^ self model selectedClass name",
 messageSends: ["name", "selectedClass", "model"],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand);
+globals.HLCopyClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "New class name:";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLCopyClassCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'New class name:'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand);
+globals.HLCopyClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._copyClassTo_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLCopyClassCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLCopyClassCommand)})},
 args: [],
 source: "execute\x0a\x09self model copyClassTo: self input",
 messageSends: ["copyClassTo:", "model", "input"],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand);
+globals.HLCopyClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedClass())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLCopyClassCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLCopyClassCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedClass notNil",
 messageSends: ["notNil", "selectedClass", "model"],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand);
+globals.HLCopyClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLCopyClassCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand);
+globals.HLCopyClassCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLCopyClassCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand.klass);
+globals.HLCopyClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Class";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLCopyClassCommand.klass)})},
+return "Copy class";
+},
 args: [],
-source: "label\x0a\x09^ 'Class'",
+source: "label\x0a\x09^ 'Copy class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand.klass);
+globals.HLCopyClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Copy class...";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLCopyClassCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x0a\x09^ 'Copy class...'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLCopyClassCommand.klass);
+globals.HLCopyClassCommand.klass);
 
 
-smalltalk.addClass('HLFindCommand', smalltalk.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLFindCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "f";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLFindCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'f'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindCommand.klass);
+globals.HLFindCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Find";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLFindCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Find'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindCommand.klass);
+globals.HLFindCommand.klass);
 
 
-smalltalk.addClass('HLFindClassCommand', smalltalk.HLFindCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLFindClassCommand', globals.HLFindCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "select a class";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLFindClassCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'select a class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand);
+globals.HLFindClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._openClassNamed_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLFindClassCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLFindClassCommand)})},
 args: [],
 source: "execute\x0a\x09self model openClassNamed: self input",
 messageSends: ["openClassNamed:", "model", "input"],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand);
+globals.HLFindClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputCompletion",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._model())._availableClassNames();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},smalltalk.HLFindClassCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},globals.HLFindClassCommand)})},
 args: [],
 source: "inputCompletion\x0a\x09^ self model availableClassNames",
 messageSends: ["availableClassNames", "model"],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand);
+globals.HLFindClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Find a class";
-}, function($ctx1) {$ctx1.fill(self,"inputLabel",{},smalltalk.HLFindClassCommand)})},
+},
 args: [],
 source: "inputLabel\x0a\x09^ 'Find a class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand);
+globals.HLFindClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLFindClassCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand);
+globals.HLFindClassCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isValidFor:",
-category: 'testing',
+protocol: 'testing',
 fn: function (aModel){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(aModel)._isBrowserModel();
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"isValidFor:",{aModel:aModel},smalltalk.HLFindClassCommand.klass)})},
+return true;
+},
 args: ["aModel"],
-source: "isValidFor: aModel\x0a\x09^ aModel isBrowserModel",
-messageSends: ["isBrowserModel"],
+source: "isValidFor: aModel\x0a\x09^ true",
+messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand.klass);
+globals.HLFindClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLFindClassCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand.klass);
+globals.HLFindClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Class";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLFindClassCommand.klass)})},
+return "Find class";
+},
 args: [],
-source: "label\x0a\x09^ 'Class'",
+source: "label\x0a\x09^ 'Find class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindClassCommand.klass);
+globals.HLFindClassCommand.klass);
 
 
-smalltalk.addClass('HLFindReferencesCommand', smalltalk.HLFindCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLFindReferencesCommand', globals.HLFindCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultInput",
-category: 'defaults',
+protocol: 'defaults',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $2,$3,$1;
-$2=_st(self._model())._selectedMethod();
+var $3,$2,$4,$1;
+$3=self._model();
+$ctx1.sendIdx["model"]=1;
+$2=_st($3)._selectedMethod();
 if(($receiver = $2) == nil || $receiver == null){
-$3=_st(self._model())._selectedClass();
-if(($receiver = $3) == nil || $receiver == null){
+$4=_st(self._model())._selectedClass();
+if(($receiver = $4) == nil || $receiver == null){
 $1="";
 } else {
 var class_;
 class_=$receiver;
-$1=_st(class_)._name();
+$1=_st(_st(class_)._theNonMetaClass())._name();
 };
 } else {
 var method;
@@ -524,1378 +585,1322 @@ method=$receiver;
 $1=_st(method)._selector();
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},smalltalk.HLFindReferencesCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},globals.HLFindReferencesCommand)})},
 args: [],
-source: "defaultInput\x0a\x09^ self model selectedMethod \x0a\x09\x09ifNil: [\x0a\x09\x09\x09self model selectedClass\x0a\x09\x09\x09\x09ifNil: [ '' ]\x0a\x09\x09\x09\x09ifNotNil: [ :class | class name ] ]\x0a\x09\x09ifNotNil: [ :method | method selector ]",
-messageSends: ["ifNil:ifNotNil:", "selectedMethod", "model", "selectedClass", "name", "selector"],
+source: "defaultInput\x0a\x09^ self model selectedMethod \x0a\x09\x09ifNil: [\x0a\x09\x09\x09self model selectedClass\x0a\x09\x09\x09\x09ifNil: [ '' ]\x0a\x09\x09\x09\x09ifNotNil: [ :class | class theNonMetaClass name ] ]\x0a\x09\x09ifNotNil: [ :method | method selector ]",
+messageSends: ["ifNil:ifNotNil:", "selectedMethod", "model", "selectedClass", "name", "theNonMetaClass", "selector"],
 referencedClasses: []
 }),
-smalltalk.HLFindReferencesCommand);
+globals.HLFindReferencesCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "find references";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLFindReferencesCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'find references'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindReferencesCommand);
+globals.HLFindReferencesCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
-function $HLReferences(){return smalltalk.HLReferences||(typeof HLReferences=="undefined"?nil:HLReferences)}
+function $HLReferences(){return globals.HLReferences||(typeof HLReferences=="undefined"?nil:HLReferences)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 $1=_st($HLReferences())._new();
 _st($1)._openAsTab();
 $2=_st($1)._search_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLFindReferencesCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLFindReferencesCommand)})},
 args: [],
 source: "execute\x0a\x09HLReferences new \x0a\x09\x09openAsTab;\x0a\x09\x09search: self input",
 messageSends: ["openAsTab", "new", "search:", "input"],
 referencedClasses: ["HLReferences"]
 }),
-smalltalk.HLFindReferencesCommand);
+globals.HLFindReferencesCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputCompletion",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(self._model())._availableClassNames()).__comma(_st(self._model())._allSelectors());
+var $3,$2,$1;
+$3=self._model();
+$ctx1.sendIdx["model"]=1;
+$2=_st($3)._availableClassNames();
+$1=_st($2).__comma(_st(self._model())._allSelectors());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},smalltalk.HLFindReferencesCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},globals.HLFindReferencesCommand)})},
 args: [],
 source: "inputCompletion\x0a\x09^ self model availableClassNames, self model allSelectors",
 messageSends: [",", "availableClassNames", "model", "allSelectors"],
 referencedClasses: []
 }),
-smalltalk.HLFindReferencesCommand);
+globals.HLFindReferencesCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Find references of";
-}, function($ctx1) {$ctx1.fill(self,"inputLabel",{},smalltalk.HLFindReferencesCommand)})},
+},
 args: [],
 source: "inputLabel\x0a\x09^ 'Find references of'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindReferencesCommand);
+globals.HLFindReferencesCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLFindReferencesCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindReferencesCommand);
+globals.HLFindReferencesCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "r";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLFindReferencesCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'r'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindReferencesCommand.klass);
+globals.HLFindReferencesCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "References";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLFindReferencesCommand.klass)})},
+return "Find references";
+},
 args: [],
-source: "label\x0a\x09^ 'References'",
+source: "label\x0a\x09^ 'Find references'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLFindReferencesCommand.klass);
+globals.HLFindReferencesCommand.klass);
 
 
-smalltalk.addClass('HLMoveToCommand', smalltalk.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLMoveToCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "m";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLMoveToCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'm'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveToCommand.klass);
+globals.HLMoveToCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Move";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLMoveToCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Move'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveToCommand.klass);
+globals.HLMoveToCommand.klass);
 
 
-smalltalk.addClass('HLMoveClassToCommand', smalltalk.HLMoveToCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLMoveClassToCommand', globals.HLMoveToCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedClass())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLMoveClassToCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLMoveClassToCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedClass notNil",
 messageSends: ["notNil", "selectedClass", "model"],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToCommand);
+globals.HLMoveClassToCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLMoveClassToCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToCommand.klass);
+globals.HLMoveClassToCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Class";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLMoveClassToCommand.klass)})},
+return "Move class";
+},
 args: [],
-source: "label\x0a\x09^ 'Class'",
+source: "label\x0a\x09^ 'Move class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToCommand.klass);
+globals.HLMoveClassToCommand.klass);
 
 
-smalltalk.addClass('HLMoveClassToPackageCommand', smalltalk.HLMoveClassToCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLMoveClassToPackageCommand', globals.HLMoveClassToCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Classes";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLMoveClassToPackageCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Classes'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand);
+globals.HLMoveClassToPackageCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "select a package";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLMoveClassToPackageCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'select a package'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand);
+globals.HLMoveClassToPackageCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._moveClassToPackage_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLMoveClassToPackageCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLMoveClassToPackageCommand)})},
 args: [],
 source: "execute\x0a\x09self model moveClassToPackage: self input",
 messageSends: ["moveClassToPackage:", "model", "input"],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand);
+globals.HLMoveClassToPackageCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputCompletion",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._model())._availablePackageNames();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},smalltalk.HLMoveClassToPackageCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},globals.HLMoveClassToPackageCommand)})},
 args: [],
 source: "inputCompletion\x0a\x09^ self model availablePackageNames",
 messageSends: ["availablePackageNames", "model"],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand);
+globals.HLMoveClassToPackageCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Move class to package:";
-}, function($ctx1) {$ctx1.fill(self,"inputLabel",{},smalltalk.HLMoveClassToPackageCommand)})},
+},
 args: [],
 source: "inputLabel\x0a\x09^ 'Move class to package:'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand);
+globals.HLMoveClassToPackageCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLMoveClassToPackageCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand);
+globals.HLMoveClassToPackageCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "p";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLMoveClassToPackageCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'p'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand.klass);
+globals.HLMoveClassToPackageCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "to package";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLMoveClassToPackageCommand.klass)})},
+return "Move class to package";
+},
 args: [],
-source: "label\x0a\x09^ 'to package'",
+source: "label\x0a\x09^ 'Move class to package'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand.klass);
+globals.HLMoveClassToPackageCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Move to package...";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLMoveClassToPackageCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x09\x0a\x09^ 'Move to package...'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveClassToPackageCommand.klass);
+globals.HLMoveClassToPackageCommand.klass);
 
 
-smalltalk.addClass('HLMoveMethodToCommand', smalltalk.HLMoveToCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLMoveMethodToCommand', globals.HLMoveToCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Methods";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLMoveMethodToCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Methods'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToCommand);
+globals.HLMoveMethodToCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedMethod())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLMoveMethodToCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLMoveMethodToCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedMethod notNil",
 messageSends: ["notNil", "selectedMethod", "model"],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToCommand);
+globals.HLMoveMethodToCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "m";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLMoveMethodToCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'm'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToCommand.klass);
+globals.HLMoveMethodToCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Method";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLMoveMethodToCommand.klass)})},
+return "Move method";
+},
 args: [],
-source: "label\x0a\x09^ 'Method'",
+source: "label\x0a\x09^ 'Move method'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToCommand.klass);
+globals.HLMoveMethodToCommand.klass);
 
 
-smalltalk.addClass('HLMoveMethodToClassCommand', smalltalk.HLMoveMethodToCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLMoveMethodToClassCommand', globals.HLMoveMethodToCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "select a class";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLMoveMethodToClassCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'select a class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand);
+globals.HLMoveMethodToClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._moveMethodToClass_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLMoveMethodToClassCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLMoveMethodToClassCommand)})},
 args: [],
 source: "execute\x0a\x09self model moveMethodToClass: self input",
 messageSends: ["moveMethodToClass:", "model", "input"],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand);
+globals.HLMoveMethodToClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputCompletion",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._model())._availableClassNames();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},smalltalk.HLMoveMethodToClassCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},globals.HLMoveMethodToClassCommand)})},
 args: [],
 source: "inputCompletion\x0a\x09^ self model availableClassNames",
 messageSends: ["availableClassNames", "model"],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand);
+globals.HLMoveMethodToClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Move method to class:";
-}, function($ctx1) {$ctx1.fill(self,"inputLabel",{},smalltalk.HLMoveMethodToClassCommand)})},
+},
 args: [],
 source: "inputLabel\x0a\x09^ 'Move method to class:'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand);
+globals.HLMoveMethodToClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLMoveMethodToClassCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand);
+globals.HLMoveMethodToClassCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLMoveMethodToClassCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand.klass);
+globals.HLMoveMethodToClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "to class";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLMoveMethodToClassCommand.klass)})},
+return "Move method to class";
+},
 args: [],
-source: "label\x09\x0a\x09^ 'to class'",
+source: "label\x09\x0a\x09^ 'Move method to class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand.klass);
+globals.HLMoveMethodToClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Move to class...";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLMoveMethodToClassCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x09\x0a\x09^ 'Move to class...'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToClassCommand.klass);
+globals.HLMoveMethodToClassCommand.klass);
 
 
-smalltalk.addClass('HLMoveMethodToProtocolCommand', smalltalk.HLMoveMethodToCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLMoveMethodToProtocolCommand', globals.HLMoveMethodToCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "select a protocol";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLMoveMethodToProtocolCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'select a protocol'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand);
+globals.HLMoveMethodToProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._moveMethodToProtocol_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLMoveMethodToProtocolCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLMoveMethodToProtocolCommand)})},
 args: [],
 source: "execute\x0a\x09self model moveMethodToProtocol: self input",
 messageSends: ["moveMethodToProtocol:", "model", "input"],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand);
+globals.HLMoveMethodToProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputCompletion",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._model())._availableProtocols();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},smalltalk.HLMoveMethodToProtocolCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"inputCompletion",{},globals.HLMoveMethodToProtocolCommand)})},
 args: [],
 source: "inputCompletion\x0a\x09^ self model availableProtocols",
 messageSends: ["availableProtocols", "model"],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand);
+globals.HLMoveMethodToProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "inputLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Move method to a protocol:";
-}, function($ctx1) {$ctx1.fill(self,"inputLabel",{},smalltalk.HLMoveMethodToProtocolCommand)})},
+},
 args: [],
 source: "inputLabel\x0a\x09^ 'Move method to a protocol:'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand);
+globals.HLMoveMethodToProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLMoveMethodToProtocolCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand);
+globals.HLMoveMethodToProtocolCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "t";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLMoveMethodToProtocolCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 't'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand.klass);
+globals.HLMoveMethodToProtocolCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "to protocol";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLMoveMethodToProtocolCommand.klass)})},
+return "Move method to protocol";
+},
 args: [],
-source: "label\x0a\x09^ 'to protocol'",
+source: "label\x0a\x09^ 'Move method to protocol'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand.klass);
+globals.HLMoveMethodToProtocolCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Move to protocol...";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLMoveMethodToProtocolCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x0a\x09^ 'Move to protocol...'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLMoveMethodToProtocolCommand.klass);
+globals.HLMoveMethodToProtocolCommand.klass);
 
 
-smalltalk.addClass('HLRemoveCommand', smalltalk.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLRemoveCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "x";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLRemoveCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'x'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveCommand.klass);
+globals.HLRemoveCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Remove";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLRemoveCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Remove'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveCommand.klass);
+globals.HLRemoveCommand.klass);
 
 
-smalltalk.addClass('HLRemoveClassCommand', smalltalk.HLRemoveCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLRemoveClassCommand', globals.HLRemoveCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Classes";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLRemoveClassCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Classes'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveClassCommand);
+globals.HLRemoveClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._removeClass();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLRemoveClassCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLRemoveClassCommand)})},
 args: [],
 source: "execute\x0a\x09self model removeClass",
 messageSends: ["removeClass", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRemoveClassCommand);
+globals.HLRemoveClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedClass())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLRemoveClassCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLRemoveClassCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedClass notNil",
 messageSends: ["notNil", "selectedClass", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRemoveClassCommand);
+globals.HLRemoveClassCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLRemoveClassCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveClassCommand.klass);
+globals.HLRemoveClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Class";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLRemoveClassCommand.klass)})},
+return "Remove class";
+},
 args: [],
-source: "label\x0a\x09^ 'Class'",
+source: "label\x0a\x09^ 'Remove class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveClassCommand.klass);
+globals.HLRemoveClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Remove class";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLRemoveClassCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x0a\x09^ 'Remove class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveClassCommand.klass);
+globals.HLRemoveClassCommand.klass);
 
 
-smalltalk.addClass('HLRemoveMethodCommand', smalltalk.HLRemoveCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLRemoveMethodCommand', globals.HLRemoveCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Methods";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLRemoveMethodCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Methods'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveMethodCommand);
+globals.HLRemoveMethodCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._removeMethod();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLRemoveMethodCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLRemoveMethodCommand)})},
 args: [],
 source: "execute\x0a\x09self model removeMethod",
 messageSends: ["removeMethod", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRemoveMethodCommand);
+globals.HLRemoveMethodCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedMethod())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLRemoveMethodCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLRemoveMethodCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedMethod notNil",
 messageSends: ["notNil", "selectedMethod", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRemoveMethodCommand);
+globals.HLRemoveMethodCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "m";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLRemoveMethodCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'm'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveMethodCommand.klass);
+globals.HLRemoveMethodCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Method";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLRemoveMethodCommand.klass)})},
+return "Remove method";
+},
 args: [],
-source: "label\x0a\x09^ 'Method'",
+source: "label\x0a\x09^ 'Remove method'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveMethodCommand.klass);
+globals.HLRemoveMethodCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Remove method";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLRemoveMethodCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x0a\x09^ 'Remove method'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveMethodCommand.klass);
+globals.HLRemoveMethodCommand.klass);
 
 
-smalltalk.addClass('HLRemoveProtocolCommand', smalltalk.HLRemoveCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLRemoveProtocolCommand', globals.HLRemoveCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Protocols";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLRemoveProtocolCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Protocols'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveProtocolCommand);
+globals.HLRemoveProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._removeProtocol();
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLRemoveProtocolCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLRemoveProtocolCommand)})},
 args: [],
 source: "execute\x0a\x09self model removeProtocol",
 messageSends: ["removeProtocol", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRemoveProtocolCommand);
+globals.HLRemoveProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedProtocol())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLRemoveProtocolCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLRemoveProtocolCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedProtocol notNil",
 messageSends: ["notNil", "selectedProtocol", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRemoveProtocolCommand);
+globals.HLRemoveProtocolCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "t";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLRemoveProtocolCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 't'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveProtocolCommand.klass);
+globals.HLRemoveProtocolCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Protocol";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLRemoveProtocolCommand.klass)})},
+return "Remove protocol";
+},
 args: [],
-source: "label\x0a\x09^ 'Protocol'",
+source: "label\x0a\x09^ 'Remove protocol'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveProtocolCommand.klass);
+globals.HLRemoveProtocolCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Remove protocol";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLRemoveProtocolCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x0a\x09^ 'Remove protocol'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRemoveProtocolCommand.klass);
+globals.HLRemoveProtocolCommand.klass);
 
 
-smalltalk.addClass('HLRenameCommand', smalltalk.HLToolCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLRenameCommand', globals.HLToolCommand, [], 'Helios-Commands-Tools');
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "r";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLRenameCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'r'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameCommand.klass);
+globals.HLRenameCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Rename";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLRenameCommand.klass)})},
+},
 args: [],
 source: "label\x0a\x09^ 'Rename'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameCommand.klass);
+globals.HLRenameCommand.klass);
 
 
-smalltalk.addClass('HLRenameClassCommand', smalltalk.HLRenameCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLRenameClassCommand', globals.HLRenameCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Classes";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLRenameClassCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Classes'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand);
+globals.HLRenameClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultInput",
-category: 'defaults',
+protocol: 'defaults',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(_st(self._model())._selectedClass())._name();
+$1=_st(_st(_st(self._model())._selectedClass())._theNonMetaClass())._name();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},smalltalk.HLRenameClassCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},globals.HLRenameClassCommand)})},
 args: [],
-source: "defaultInput\x0a\x09^ self model selectedClass name",
-messageSends: ["name", "selectedClass", "model"],
+source: "defaultInput\x0a\x09^ self model selectedClass theNonMetaClass name",
+messageSends: ["name", "theNonMetaClass", "selectedClass", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand);
+globals.HLRenameClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Rename class to:";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLRenameClassCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'Rename class to:'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand);
+globals.HLRenameClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._renameClassTo_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLRenameClassCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLRenameClassCommand)})},
 args: [],
 source: "execute\x0a\x09self model renameClassTo: self input",
 messageSends: ["renameClassTo:", "model", "input"],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand);
+globals.HLRenameClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedClass())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLRenameClassCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLRenameClassCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedClass notNil",
 messageSends: ["notNil", "selectedClass", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand);
+globals.HLRenameClassCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLRenameClassCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand);
+globals.HLRenameClassCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "c";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLRenameClassCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 'c'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand.klass);
+globals.HLRenameClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Class";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLRenameClassCommand.klass)})},
+return "Rename class";
+},
 args: [],
-source: "label\x0a\x09^ 'Class'",
+source: "label\x0a\x09^ 'Rename class'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand.klass);
+globals.HLRenameClassCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Rename class...";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLRenameClassCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x0a\x09^ 'Rename class...'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameClassCommand.klass);
+globals.HLRenameClassCommand.klass);
 
 
-smalltalk.addClass('HLRenameProtocolCommand', smalltalk.HLRenameCommand, [], 'Helios-Commands-Tools');
+smalltalk.addClass('HLRenameProtocolCommand', globals.HLRenameCommand, [], 'Helios-Commands-Tools');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "category",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Protocols";
-}, function($ctx1) {$ctx1.fill(self,"category",{},smalltalk.HLRenameProtocolCommand)})},
+},
 args: [],
 source: "category\x0a\x09^ 'Protocols'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand);
+globals.HLRenameProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultInput",
-category: 'defaults',
+protocol: 'defaults',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._model())._selectedProtocol();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},smalltalk.HLRenameProtocolCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"defaultInput",{},globals.HLRenameProtocolCommand)})},
 args: [],
 source: "defaultInput\x0a\x09^ self model selectedProtocol",
 messageSends: ["selectedProtocol", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand);
+globals.HLRenameProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "displayLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Rename protocol to:";
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLRenameProtocolCommand)})},
+},
 args: [],
 source: "displayLabel\x0a\x09^ 'Rename protocol to:'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand);
+globals.HLRenameProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "execute",
-category: 'executing',
+protocol: 'executing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._model())._renameProtocolTo_(self._input());
-return self}, function($ctx1) {$ctx1.fill(self,"execute",{},smalltalk.HLRenameProtocolCommand)})},
+return self}, function($ctx1) {$ctx1.fill(self,"execute",{},globals.HLRenameProtocolCommand)})},
 args: [],
 source: "execute\x0a\x09self model renameProtocolTo: self input",
 messageSends: ["renameProtocolTo:", "model", "input"],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand);
+globals.HLRenameProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isActive",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._model())._selectedProtocol())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isActive",{},smalltalk.HLRenameProtocolCommand)})},
+}, function($ctx1) {$ctx1.fill(self,"isActive",{},globals.HLRenameProtocolCommand)})},
 args: [],
 source: "isActive\x0a\x09^ self model selectedProtocol notNil",
 messageSends: ["notNil", "selectedProtocol", "model"],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand);
+globals.HLRenameProtocolCommand);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isInputRequired",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isInputRequired",{},smalltalk.HLRenameProtocolCommand)})},
+},
 args: [],
 source: "isInputRequired\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand);
+globals.HLRenameProtocolCommand);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "key",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "t";
-}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLRenameProtocolCommand.klass)})},
+},
 args: [],
 source: "key\x0a\x09^ 't'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand.klass);
+globals.HLRenameProtocolCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "label",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return "Protocol";
-}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLRenameProtocolCommand.klass)})},
+return "Rename protocol";
+},
 args: [],
-source: "label\x0a\x09^ 'Protocol'",
+source: "label\x0a\x09^ 'Rename protocol'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand.klass);
+globals.HLRenameProtocolCommand.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "menuLabel",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "Rename protocol...";
-}, function($ctx1) {$ctx1.fill(self,"menuLabel",{},smalltalk.HLRenameProtocolCommand.klass)})},
+},
 args: [],
 source: "menuLabel\x0a\x09^ 'Rename protocol...'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLRenameProtocolCommand.klass);
+globals.HLRenameProtocolCommand.klass);
 
 });

File diff suppressed because it is too large
+ 241 - 176
js/Helios-Core.js


File diff suppressed because it is too large
+ 355 - 187
js/Helios-Debugger.js


+ 9 - 3
js/Helios-Exceptions.js

@@ -1,10 +1,16 @@
-define("amber_core/Helios-Exceptions", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Exceptions"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Exceptions", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Exceptions"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Exceptions');
 smalltalk.packages["Helios-Exceptions"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLError', smalltalk.Error, [], 'Helios-Exceptions');
+smalltalk.addClass('HLError', globals.Error, [], 'Helios-Exceptions');
+globals.HLError.comment="I am the abstract superclass of all Helios-specific errors.";
 
 
-smalltalk.addClass('HLChangeForbidden', smalltalk.HLError, [], 'Helios-Exceptions');
+smalltalk.addClass('HLChangeForbidden', globals.HLError, [], 'Helios-Exceptions');
+globals.HLChangeForbidden.comment="I get signaled when a (often user) requested change is forbidden. A confirmation message can then be displayed to the user.\x0a\x0aSee `HLModel >> withChangesDo:`.";
+
+
+smalltalk.addClass('HLListItemNotFound', globals.HLError, [], 'Helios-Exceptions');
+globals.HLListItemNotFound.comment="I get signaled by a `HLListWidget` when a non-existing item in the list is activated.";
 
 });

+ 1051 - 0
js/Helios-Helpers.js

@@ -0,0 +1,1051 @@
+define("amber_core/Helios-Helpers", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
+smalltalk.addPackage('Helios-Helpers');
+smalltalk.packages["Helios-Helpers"].transport = {"type":"amd","amdNamespace":"amber_core"};
+
+smalltalk.addClass('HLClassifier', globals.Object, ['next', 'method'], 'Helios-Helpers');
+globals.HLClassifier.comment="I am an abstract class implementing a link in a `chain of responsibility` pattern.\x0a\x0aSubclasses are in charge of classifying a method according to multiple strategies.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "classify",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$2;
+$1=self._next();
+$ctx1.sendIdx["next"]=1;
+if(($receiver = $1) == nil || $receiver == null){
+return false;
+} else {
+$1;
+};
+$3=self._doClassify();
+if(smalltalk.assert($3)){
+$2=true;
+} else {
+$2=_st(self._next())._classify();
+};
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"classify",{},globals.HLClassifier)})},
+args: [],
+source: "classify\x0a\x09self next ifNil: [ ^ false ].\x0a\x09\x0a\x09^ self doClassify\x0a\x09\x09ifTrue: [ true ]\x0a\x09\x09ifFalse: [ self next classify ]",
+messageSends: ["ifNil:", "next", "ifTrue:ifFalse:", "doClassify", "classify"],
+referencedClasses: []
+}),
+globals.HLClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "doClassify",
+protocol: 'private',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._subclassResponsibility();
+return self}, function($ctx1) {$ctx1.fill(self,"doClassify",{},globals.HLClassifier)})},
+args: [],
+source: "doClassify\x0a\x09self subclassResponsibility",
+messageSends: ["subclassResponsibility"],
+referencedClasses: []
+}),
+globals.HLClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "method",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@method"];
+return $1;
+},
+args: [],
+source: "method\x0a\x09^ method",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "method:",
+protocol: 'accessing',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+self["@method"]=anObject;
+$1=self._next();
+if(($receiver = $1) == nil || $receiver == null){
+$1;
+} else {
+var nextLink;
+nextLink=$receiver;
+_st(nextLink)._method_(anObject);
+};
+return self}, function($ctx1) {$ctx1.fill(self,"method:",{anObject:anObject},globals.HLClassifier)})},
+args: ["anObject"],
+source: "method: anObject\x0a\x09method := anObject.\x0a\x09self next\x0a\x09\x09ifNotNil: [ :nextLink | nextLink method: anObject ]",
+messageSends: ["ifNotNil:", "next", "method:"],
+referencedClasses: []
+}),
+globals.HLClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "next",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@next"];
+return $1;
+},
+args: [],
+source: "next\x0a\x09^ next",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "next:",
+protocol: 'accessing',
+fn: function (anObject){
+var self=this;
+self["@next"]=anObject;
+return self},
+args: ["anObject"],
+source: "next: anObject\x0a\x09next := anObject",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLClassifier);
+
+
+
+smalltalk.addClass('HLAccessorClassifier', globals.HLClassifier, [], 'Helios-Helpers');
+globals.HLAccessorClassifier.comment="I am a classifier checking the method selector matches an instance variable name.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "doClassify",
+protocol: 'private',
+fn: function (){
+var self=this;
+var names,selector;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+names=_st(_st(self["@method"])._methodClass())._allInstanceVariableNames();
+selector=_st(self["@method"])._selector();
+$1=_st(_st(selector)._last()).__eq(":");
+if(smalltalk.assert($1)){
+selector=_st(selector)._allButLast();
+selector;
+};
+$2=_st(names)._includes_(selector);
+if(! smalltalk.assert($2)){
+return false;
+};
+_st(self["@method"])._protocol_("accessing");
+return true;
+}, function($ctx1) {$ctx1.fill(self,"doClassify",{names:names,selector:selector},globals.HLAccessorClassifier)})},
+args: [],
+source: "doClassify\x0a\x09| names selector |\x0a\x09\x0a\x09names := method methodClass allInstanceVariableNames.\x0a\x09selector := method selector.\x0a\x09\x0a\x09(selector last = ':')\x0a\x09\x09ifTrue: [ \x22selector might be a setter\x22\x0a\x09\x09\x09selector := selector allButLast ].\x0a\x09\x0a\x09(names includes: selector)\x0a\x09\x09ifFalse: [ ^ false ].\x0a\x09\x09\x0a\x09method protocol: 'accessing'.\x0a\x09^ true.",
+messageSends: ["allInstanceVariableNames", "methodClass", "selector", "ifTrue:", "=", "last", "allButLast", "ifFalse:", "includes:", "protocol:"],
+referencedClasses: []
+}),
+globals.HLAccessorClassifier);
+
+
+
+smalltalk.addClass('HLImplementorClassifier', globals.HLClassifier, [], 'Helios-Helpers');
+globals.HLImplementorClassifier.comment="I am a classifier checking the other implementations of the same selector and choose the protocol the most populated.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "doClassify",
+protocol: 'private',
+fn: function (){
+var self=this;
+var currentClass;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$4,$2;
+var $early={};
+try {
+currentClass=_st(self["@method"])._methodClass();
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(currentClass)._superclass();
+$ctx2.sendIdx["superclass"]=1;
+return _st($1)._isNil();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._whileFalse_((function(){
+return smalltalk.withContext(function($ctx2) {
+currentClass=_st(currentClass)._superclass();
+currentClass;
+$3=currentClass;
+$4=_st(self["@method"])._selector();
+$ctx2.sendIdx["selector"]=1;
+$2=_st($3)._includesSelector_($4);
+if(smalltalk.assert($2)){
+_st(self["@method"])._protocol_(_st(_st(currentClass).__gt_gt(_st(self["@method"])._selector()))._protocol());
+throw $early=[true];
+};
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
+return false;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"doClassify",{currentClass:currentClass},globals.HLImplementorClassifier)})},
+args: [],
+source: "doClassify\x0a\x09| currentClass |\x0a\x09currentClass := method methodClass.\x0a\x09\x0a\x09[ currentClass superclass isNil ] whileFalse: [\x0a\x09\x09currentClass := currentClass superclass.\x0a\x09\x09(currentClass includesSelector: method selector)\x0a\x09\x09\x09ifTrue: [ \x0a\x09\x09\x09\x09method protocol: (currentClass >> method selector) protocol.\x0a\x09\x09\x09\x09^ true ]].\x0a\x09\x0a\x09^ false.",
+messageSends: ["methodClass", "whileFalse:", "isNil", "superclass", "ifTrue:", "includesSelector:", "selector", "protocol:", "protocol", ">>"],
+referencedClasses: []
+}),
+globals.HLImplementorClassifier);
+
+
+
+smalltalk.addClass('HLPrefixClassifier', globals.HLClassifier, ['prefixMapping'], 'Helios-Helpers');
+globals.HLPrefixClassifier.comment="I am classifier checking the method selector to know if it begins with a known prefix.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "buildPrefixDictionary",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+function $Dictionary(){return globals.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+self["@prefixMapping"]=_st($Dictionary())._new();
+$1=self["@prefixMapping"];
+_st($1)._at_put_("test","tests");
+$ctx1.sendIdx["at:put:"]=1;
+_st($1)._at_put_("bench","benchmarking");
+$ctx1.sendIdx["at:put:"]=2;
+_st($1)._at_put_("copy","copying");
+$ctx1.sendIdx["at:put:"]=3;
+_st($1)._at_put_("initialize","initialization");
+$ctx1.sendIdx["at:put:"]=4;
+_st($1)._at_put_("accept","visitor");
+$ctx1.sendIdx["at:put:"]=5;
+_st($1)._at_put_("visit","visitor");
+$ctx1.sendIdx["at:put:"]=6;
+_st($1)._at_put_("signal","signalling");
+$ctx1.sendIdx["at:put:"]=7;
+_st($1)._at_put_("parse","parsing");
+$ctx1.sendIdx["at:put:"]=8;
+_st($1)._at_put_("add","adding");
+$ctx1.sendIdx["at:put:"]=9;
+_st($1)._at_put_("is","testing");
+$ctx1.sendIdx["at:put:"]=10;
+_st($1)._at_put_("as","converting");
+$ctx1.sendIdx["at:put:"]=11;
+$2=_st($1)._at_put_("new","instance creation");
+return self}, function($ctx1) {$ctx1.fill(self,"buildPrefixDictionary",{},globals.HLPrefixClassifier)})},
+args: [],
+source: "buildPrefixDictionary\x0a\x09prefixMapping := Dictionary new.\x0a\x09prefixMapping \x0a\x09\x09at: 'test' put: 'tests';\x0a\x09 \x09at: 'bench' put: 'benchmarking';\x0a\x09 \x09at: 'copy' put: 'copying';\x0a\x09\x09at: 'initialize' put: 'initialization';\x0a\x09\x09at: 'accept' put: 'visitor';\x0a\x09\x09at: 'visit' put: 'visitor';\x0a\x09\x09at: 'signal' put: 'signalling';\x0a\x09\x09at: 'parse' put: 'parsing';\x0a\x09\x09at: 'add' put: 'adding';\x0a\x09\x09at: 'is' put: 'testing';\x0a\x09\x09at: 'as' put: 'converting';\x0a\x09\x09at: 'new' put: 'instance creation'.",
+messageSends: ["new", "at:put:"],
+referencedClasses: ["Dictionary"]
+}),
+globals.HLPrefixClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "doClassify",
+protocol: 'private',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+var $early={};
+try {
+_st(self["@prefixMapping"])._keysAndValuesDo_((function(prefix,protocol){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(_st(self["@method"])._selector())._beginsWith_(prefix);
+if(smalltalk.assert($1)){
+_st(self["@method"])._protocol_(protocol);
+throw $early=[true];
+};
+}, function($ctx2) {$ctx2.fillBlock({prefix:prefix,protocol:protocol},$ctx1,1)})}));
+return false;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"doClassify",{},globals.HLPrefixClassifier)})},
+args: [],
+source: "doClassify\x0a\x09prefixMapping keysAndValuesDo: [ :prefix :protocol |\x0a\x09\x09(method selector beginsWith: prefix)\x0a\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09method protocol: protocol.\x0a\x09\x09\x09\x09^ true ]].\x0a\x09^ false.",
+messageSends: ["keysAndValuesDo:", "ifTrue:", "beginsWith:", "selector", "protocol:"],
+referencedClasses: []
+}),
+globals.HLPrefixClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+globals.HLPrefixClassifier.superclass.fn.prototype._initialize.apply(_st(self), []);
+self._buildPrefixDictionary();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.HLPrefixClassifier)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x0a\x09self buildPrefixDictionary",
+messageSends: ["initialize", "buildPrefixDictionary"],
+referencedClasses: []
+}),
+globals.HLPrefixClassifier);
+
+
+
+smalltalk.addClass('HLSuperclassClassifier', globals.HLClassifier, [], 'Helios-Helpers');
+globals.HLSuperclassClassifier.comment="I am a classifier checking the superclass chain to find a matching selector.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "doClassify",
+protocol: 'private',
+fn: function (){
+var self=this;
+var protocolBag,methods,protocolToUse,counter;
+function $Dictionary(){return globals.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+function $HLReferencesModel(){return globals.HLReferencesModel||(typeof HLReferencesModel=="undefined"?nil:HLReferencesModel)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1,$4,$3,$5;
+var $early={};
+try {
+protocolBag=_st($Dictionary())._new();
+$ctx1.sendIdx["new"]=1;
+methods=_st(_st($HLReferencesModel())._new())._implementorsOf_(_st(self["@method"])._selector());
+_st(methods)._ifEmpty_ifNotEmpty_((function(){
+throw $early=[false];
+}),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(methods)._do_((function(aMethod){
+var protocol;
+return smalltalk.withContext(function($ctx3) {
+protocol=_st(_st(aMethod)._method())._protocol();
+protocol;
+$2=_st(self["@method"])._methodClass();
+$ctx3.sendIdx["methodClass"]=1;
+$1=_st($2).__eq(_st(aMethod)._methodClass());
+$ctx3.sendIdx["="]=1;
+if(! smalltalk.assert($1)){
+$4=_st(_st(protocol)._first()).__eq("*");
+$ctx3.sendIdx["="]=2;
+$3=_st($4)._or_((function(){
+return smalltalk.withContext(function($ctx4) {
+return _st(protocol).__eq(_st(self["@method"])._defaultProtocol());
+}, function($ctx4) {$ctx4.fillBlock({},$ctx3,5)})}));
+if(! smalltalk.assert($3)){
+return _st(protocolBag)._at_put_(protocol,_st(_st(protocolBag)._at_ifAbsent_(protocol,(function(){
+return (0);
+}))).__plus((1)));
+};
+};
+}, function($ctx3) {$ctx3.fillBlock({aMethod:aMethod,protocol:protocol},$ctx2,3)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
+_st(protocolBag)._ifEmpty_((function(){
+throw $early=[false];
+}));
+protocolToUse=nil;
+counter=(0);
+_st(protocolBag)._keysAndValuesDo_((function(key,value){
+return smalltalk.withContext(function($ctx2) {
+$5=_st(value).__gt(counter);
+if(smalltalk.assert($5)){
+counter=value;
+counter;
+protocolToUse=key;
+return protocolToUse;
+};
+}, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1,9)})}));
+_st(self["@method"])._protocol_(protocolToUse);
+return true;
+}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"doClassify",{protocolBag:protocolBag,methods:methods,protocolToUse:protocolToUse,counter:counter},globals.HLSuperclassClassifier)})},
+args: [],
+source: "doClassify\x0a\x09| protocolBag methods protocolToUse counter |\x0a\x09\x0a\x09protocolBag := Dictionary new.\x0a\x09methods := HLReferencesModel new implementorsOf: method selector.\x0a\x09methods\x0a\x09\x09ifEmpty: [ ^ false ]\x0a\x09\x09ifNotEmpty: [\x0a\x09\x09\x09methods \x0a\x09\x09\x09\x09do: [ :aMethod || protocol |\x0a\x09\x09\x09\x09\x09protocol := aMethod method protocol.\x0a\x09\x09\x09\x09\x09(method methodClass = aMethod methodClass)\x0a\x09\x09\x09\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09\x09\x09((protocol first = '*') or: [ protocol = method defaultProtocol ])\x0a\x09\x09\x09\x09\x09\x09\x09ifFalse: [ \x0a\x09\x09\x09\x09\x09\x09\x09\x09protocolBag \x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09at: protocol \x0a\x09\x09\x09\x09\x09\x09\x09\x09\x09put: (protocolBag at: protocol ifAbsent: [ 0 ]) + 1 ] ] ] ].\x0a\x09\x09\x09\x0a\x09protocolBag ifEmpty: [ ^ false ].\x0a\x09protocolToUse := nil.\x0a\x09counter := 0.\x0a\x09protocolBag keysAndValuesDo: [ :key :value | value > counter \x0a\x09\x09ifTrue: [\x0a\x09\x09\x09counter := value.\x0a\x09\x09\x09protocolToUse := key ] ].\x0a\x09method protocol: protocolToUse.\x0a\x09^ true",
+messageSends: ["new", "implementorsOf:", "selector", "ifEmpty:ifNotEmpty:", "do:", "protocol", "method", "ifFalse:", "=", "methodClass", "or:", "first", "defaultProtocol", "at:put:", "+", "at:ifAbsent:", "ifEmpty:", "keysAndValuesDo:", "ifTrue:", ">", "protocol:"],
+referencedClasses: ["Dictionary", "HLReferencesModel"]
+}),
+globals.HLSuperclassClassifier);
+
+
+
+smalltalk.addClass('HLGenerationOutput', globals.Object, ['sourceCodes', 'protocol', 'targetClass'], 'Helios-Helpers');
+globals.HLGenerationOutput.comment="I am a simple data object used to store the result of a generation process.";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addSourceCode:",
+protocol: 'protocol',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@sourceCodes"])._add_(aString);
+return self}, function($ctx1) {$ctx1.fill(self,"addSourceCode:",{aString:aString},globals.HLGenerationOutput)})},
+args: ["aString"],
+source: "addSourceCode: aString\x0a\x09sourceCodes add: aString",
+messageSends: ["add:"],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "compile",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(self["@sourceCodes"])._do_((function(methodSourceCode){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(self["@targetClass"])._includesSelector_(_st(methodSourceCode)._selector());
+if(! smalltalk.assert($1)){
+return _st(self["@targetClass"])._compile_protocol_(_st(methodSourceCode)._sourceCode(),self["@protocol"]);
+};
+}, function($ctx2) {$ctx2.fillBlock({methodSourceCode:methodSourceCode},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"compile",{},globals.HLGenerationOutput)})},
+args: [],
+source: "compile\x0a\x09sourceCodes do: [ :methodSourceCode |\x0a\x09\x09(targetClass includesSelector: methodSourceCode selector)\x0a\x09\x09\x09ifFalse: [ \x0a\x09\x09\x09\x09targetClass \x0a\x09\x09\x09\x09\x09compile: methodSourceCode sourceCode\x0a\x09\x09\x09\x09\x09protocol: protocol ] ]",
+messageSends: ["do:", "ifFalse:", "includesSelector:", "selector", "compile:protocol:", "sourceCode"],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+function $OrderedCollection(){return globals.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+globals.HLGenerationOutput.superclass.fn.prototype._initialize.apply(_st(self), []);
+self["@sourceCodes"]=_st($OrderedCollection())._new();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.HLGenerationOutput)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09\x0a\x09sourceCodes := OrderedCollection new",
+messageSends: ["initialize", "new"],
+referencedClasses: ["OrderedCollection"]
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "protocol",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@protocol"];
+return $1;
+},
+args: [],
+source: "protocol\x0a\x09^ protocol",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "protocol:",
+protocol: 'accessing',
+fn: function (aString){
+var self=this;
+self["@protocol"]=aString;
+return self},
+args: ["aString"],
+source: "protocol: aString\x0a\x09protocol := aString",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCodes",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@sourceCodes"];
+return $1;
+},
+args: [],
+source: "sourceCodes\x0a\x09^ sourceCodes",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCodes:",
+protocol: 'accessing',
+fn: function (aCollection){
+var self=this;
+self["@sourceCodes"]=aCollection;
+return self},
+args: ["aCollection"],
+source: "sourceCodes: aCollection\x0a\x09sourceCodes := aCollection",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClass",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@targetClass"];
+return $1;
+},
+args: [],
+source: "targetClass\x0a\x09^ targetClass",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClass:",
+protocol: 'accessing',
+fn: function (aClass){
+var self=this;
+self["@targetClass"]=aClass;
+return self},
+args: ["aClass"],
+source: "targetClass: aClass\x0a\x09targetClass := aClass",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLGenerationOutput);
+
+
+
+smalltalk.addClass('HLMethodClassifier', globals.Object, ['firstClassifier'], 'Helios-Helpers');
+globals.HLMethodClassifier.comment="I am in charge of categorizing methods following this strategy:\x0a\x0a- is it an accessor?\x0a- is it overriding a superclass method?\x0a- is it starting with a know prefix?\x0a- how are categorized the other implementations?";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "addClassifier:",
+protocol: 'private',
+fn: function (aClassifier){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aClassifier)._next_(self["@firstClassifier"]);
+self["@firstClassifier"]=aClassifier;
+return self}, function($ctx1) {$ctx1.fill(self,"addClassifier:",{aClassifier:aClassifier},globals.HLMethodClassifier)})},
+args: ["aClassifier"],
+source: "addClassifier: aClassifier\x0a\x09aClassifier next: firstClassifier.\x0a\x09firstClassifier := aClassifier",
+messageSends: ["next:"],
+referencedClasses: []
+}),
+globals.HLMethodClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "classify:",
+protocol: 'protocol',
+fn: function (aMethod){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=self["@firstClassifier"];
+_st($1)._method_(aMethod);
+$2=_st($1)._classify();
+return self}, function($ctx1) {$ctx1.fill(self,"classify:",{aMethod:aMethod},globals.HLMethodClassifier)})},
+args: ["aMethod"],
+source: "classify: aMethod\x0a\x09firstClassifier\x0a\x09\x09method: aMethod;\x0a\x09\x09classify",
+messageSends: ["method:", "classify"],
+referencedClasses: []
+}),
+globals.HLMethodClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "classifyAll:",
+protocol: 'protocol',
+fn: function (aCollectionOfMethods){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(aCollectionOfMethods)._do_((function(method){
+return smalltalk.withContext(function($ctx2) {
+return self._classify_(method);
+}, function($ctx2) {$ctx2.fillBlock({method:method},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"classifyAll:",{aCollectionOfMethods:aCollectionOfMethods},globals.HLMethodClassifier)})},
+args: ["aCollectionOfMethods"],
+source: "classifyAll: aCollectionOfMethods\x0a\x09aCollectionOfMethods do: [ :method |\x0a\x09\x09self classify: method ]",
+messageSends: ["do:", "classify:"],
+referencedClasses: []
+}),
+globals.HLMethodClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+globals.HLMethodClassifier.superclass.fn.prototype._initialize.apply(_st(self), []);
+self._setupClassifiers();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.HLMethodClassifier)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09\x0a\x09self setupClassifiers",
+messageSends: ["initialize", "setupClassifiers"],
+referencedClasses: []
+}),
+globals.HLMethodClassifier);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupClassifiers",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+function $HLImplementorClassifier(){return globals.HLImplementorClassifier||(typeof HLImplementorClassifier=="undefined"?nil:HLImplementorClassifier)}
+function $HLPrefixClassifier(){return globals.HLPrefixClassifier||(typeof HLPrefixClassifier=="undefined"?nil:HLPrefixClassifier)}
+function $HLSuperclassClassifier(){return globals.HLSuperclassClassifier||(typeof HLSuperclassClassifier=="undefined"?nil:HLSuperclassClassifier)}
+function $HLAccessorClassifier(){return globals.HLAccessorClassifier||(typeof HLAccessorClassifier=="undefined"?nil:HLAccessorClassifier)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
+$1=_st($HLImplementorClassifier())._new();
+$ctx1.sendIdx["new"]=1;
+self._addClassifier_($1);
+$ctx1.sendIdx["addClassifier:"]=1;
+$2=_st($HLPrefixClassifier())._new();
+$ctx1.sendIdx["new"]=2;
+self._addClassifier_($2);
+$ctx1.sendIdx["addClassifier:"]=2;
+$3=_st($HLSuperclassClassifier())._new();
+$ctx1.sendIdx["new"]=3;
+self._addClassifier_($3);
+$ctx1.sendIdx["addClassifier:"]=3;
+self._addClassifier_(_st($HLAccessorClassifier())._new());
+return self}, function($ctx1) {$ctx1.fill(self,"setupClassifiers",{},globals.HLMethodClassifier)})},
+args: [],
+source: "setupClassifiers\x0a\x09self addClassifier: HLImplementorClassifier new.\x0a\x09self addClassifier: HLPrefixClassifier new.\x0a\x09self addClassifier: HLSuperclassClassifier new.\x0a\x09self addClassifier: HLAccessorClassifier new",
+messageSends: ["addClassifier:", "new"],
+referencedClasses: ["HLImplementorClassifier", "HLPrefixClassifier", "HLSuperclassClassifier", "HLAccessorClassifier"]
+}),
+globals.HLMethodClassifier);
+
+
+
+smalltalk.addClass('HLMethodGenerator', globals.Object, ['output'], 'Helios-Helpers');
+globals.HLMethodGenerator.comment="I am the abstract super class of the method generators.\x0a\x0aMy main method is `generate` which produce an `output` object";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "class:",
+protocol: 'accessing',
+fn: function (aClass){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._targetClass_(aClass);
+return self}, function($ctx1) {$ctx1.fill(self,"class:",{aClass:aClass},globals.HLMethodGenerator)})},
+args: ["aClass"],
+source: "class: aClass\x0a\x09output targetClass: aClass",
+messageSends: ["targetClass:"],
+referencedClasses: []
+}),
+globals.HLMethodGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generate",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self["@output"])._targetClass();
+if(($receiver = $1) == nil || $receiver == null){
+self._error_("class should not be nil");
+} else {
+$1;
+};
+return self}, function($ctx1) {$ctx1.fill(self,"generate",{},globals.HLMethodGenerator)})},
+args: [],
+source: "generate\x0a\x09output targetClass ifNil: [ self error: 'class should not be nil'].",
+messageSends: ["ifNil:", "targetClass", "error:"],
+referencedClasses: []
+}),
+globals.HLMethodGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+protocol: 'initialization',
+fn: function (){
+var self=this;
+function $HLGenerationOutput(){return globals.HLGenerationOutput||(typeof HLGenerationOutput=="undefined"?nil:HLGenerationOutput)}
+return smalltalk.withContext(function($ctx1) { 
+globals.HLMethodGenerator.superclass.fn.prototype._initialize.apply(_st(self), []);
+self["@output"]=_st($HLGenerationOutput())._new();
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.HLMethodGenerator)})},
+args: [],
+source: "initialize\x0a\x09super initialize.\x0a\x09\x0a\x09output := HLGenerationOutput new",
+messageSends: ["initialize", "new"],
+referencedClasses: ["HLGenerationOutput"]
+}),
+globals.HLMethodGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "output",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@output"];
+return $1;
+},
+args: [],
+source: "output\x0a\x09^ output",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLMethodGenerator);
+
+
+
+smalltalk.addClass('HLAccessorsGenerator', globals.HLMethodGenerator, [], 'Helios-Helpers');
+globals.HLAccessorsGenerator.comment="I am a generator used to compile the getters/setters of a class";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "accessorProtocolForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._protocol_("accessing");
+return self}, function($ctx1) {$ctx1.fill(self,"accessorProtocolForObject",{},globals.HLAccessorsGenerator)})},
+args: [],
+source: "accessorProtocolForObject\x0a\x09output protocol: 'accessing'",
+messageSends: ["protocol:"],
+referencedClasses: []
+}),
+globals.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "accessorsForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+var sources;
+function $OrderedCollection(){return globals.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+sources=_st($OrderedCollection())._new();
+_st(_st(_st(_st(self["@output"])._targetClass())._instanceVariableNames())._sorted())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+$1=sources;
+_st($1)._add_(self._getterFor_(each));
+$ctx2.sendIdx["add:"]=1;
+$2=_st($1)._add_(self._setterFor_(each));
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+_st(self["@output"])._sourceCodes_(sources);
+return self}, function($ctx1) {$ctx1.fill(self,"accessorsForObject",{sources:sources},globals.HLAccessorsGenerator)})},
+args: [],
+source: "accessorsForObject\x0a\x09| sources |\x0a\x09\x0a\x09sources := OrderedCollection new.\x0a\x09output targetClass instanceVariableNames sorted do: [ :each | \x0a\x09\x09sources \x0a\x09\x09\x09add: (self getterFor: each);\x0a\x09\x09\x09add: (self setterFor: each) ].\x0a\x09output sourceCodes: sources",
+messageSends: ["new", "do:", "sorted", "instanceVariableNames", "targetClass", "add:", "getterFor:", "setterFor:", "sourceCodes:"],
+referencedClasses: ["OrderedCollection"]
+}),
+globals.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generate",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+globals.HLAccessorsGenerator.superclass.fn.prototype._generate.apply(_st(self), []);
+$1=_st(self["@output"])._targetClass();
+_st($1)._accessorsSourceCodesWith_(self);
+$2=_st($1)._accessorProtocolWith_(self);
+return self}, function($ctx1) {$ctx1.fill(self,"generate",{},globals.HLAccessorsGenerator)})},
+args: [],
+source: "generate\x0a\x09super generate.\x0a\x09\x0a\x09output targetClass \x0a\x09\x09accessorsSourceCodesWith: self;\x0a\x09\x09accessorProtocolWith: self",
+messageSends: ["generate", "accessorsSourceCodesWith:", "targetClass", "accessorProtocolWith:"],
+referencedClasses: []
+}),
+globals.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "getterFor:",
+protocol: 'private',
+fn: function (anInstanceVariable){
+var self=this;
+function $HLMethodSourceCode(){return globals.HLMethodSourceCode||(typeof HLMethodSourceCode=="undefined"?nil:HLMethodSourceCode)}
+function $String(){return globals.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=_st($HLMethodSourceCode())._new();
+_st($2)._selector_(anInstanceVariable);
+$3=_st($2)._sourceCode_(_st($String())._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
+_st(stream).__lt_lt(anInstanceVariable);
+$ctx2.sendIdx["<<"]=1;
+_st(_st(stream)._cr())._tab();
+return _st(_st(stream).__lt_lt("^ ")).__lt_lt(anInstanceVariable);
+$ctx2.sendIdx["<<"]=2;
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)})})));
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"getterFor:",{anInstanceVariable:anInstanceVariable},globals.HLAccessorsGenerator)})},
+args: ["anInstanceVariable"],
+source: "getterFor: anInstanceVariable\x0a\x09^ HLMethodSourceCode new\x0a\x09\x09selector:anInstanceVariable;\x0a\x09\x09sourceCode: (String streamContents: [ :stream |\x0a\x09\x09stream << anInstanceVariable.\x0a\x09\x09stream cr tab.\x0a\x09\x09stream << '^ ' << anInstanceVariable ])",
+messageSends: ["selector:", "new", "sourceCode:", "streamContents:", "<<", "tab", "cr"],
+referencedClasses: ["HLMethodSourceCode", "String"]
+}),
+globals.HLAccessorsGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setterFor:",
+protocol: 'private',
+fn: function (anInstanceVariable){
+var self=this;
+function $HLMethodSourceCode(){return globals.HLMethodSourceCode||(typeof HLMethodSourceCode=="undefined"?nil:HLMethodSourceCode)}
+function $String(){return globals.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$4,$3,$1;
+$2=_st($HLMethodSourceCode())._new();
+_st($2)._selector_(_st(anInstanceVariable).__comma(":"));
+$3=_st($2)._sourceCode_(_st($String())._streamContents_((function(stream){
+return smalltalk.withContext(function($ctx2) {
+$4=_st(stream).__lt_lt(anInstanceVariable);
+$ctx2.sendIdx["<<"]=2;
+_st($4).__lt_lt(": anObject");
+$ctx2.sendIdx["<<"]=1;
+_st(_st(stream)._cr())._tab();
+return _st(_st(stream).__lt_lt(anInstanceVariable)).__lt_lt(" := anObject");
+$ctx2.sendIdx["<<"]=3;
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1,1)})})));
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"setterFor:",{anInstanceVariable:anInstanceVariable},globals.HLAccessorsGenerator)})},
+args: ["anInstanceVariable"],
+source: "setterFor: anInstanceVariable\x0a\x09^ HLMethodSourceCode new\x0a\x09\x09selector: anInstanceVariable, ':';\x0a\x09\x09sourceCode: (String streamContents: [ :stream |\x0a\x09\x09stream << anInstanceVariable << ': anObject'.\x0a\x09\x09stream cr tab.\x0a\x09\x09stream << anInstanceVariable << ' := anObject' ])",
+messageSends: ["selector:", "new", ",", "sourceCode:", "streamContents:", "<<", "tab", "cr"],
+referencedClasses: ["HLMethodSourceCode", "String"]
+}),
+globals.HLAccessorsGenerator);
+
+
+
+smalltalk.addClass('HLInitializeGenerator', globals.HLMethodGenerator, [], 'Helios-Helpers');
+globals.HLInitializeGenerator.comment="I am used to double-dispatch the `initialize` method(s) generation.\x0a\x0aUsage:\x0a\x0a    ^ HLInitializeGenerator new\x0a        class: aClass;\x0a        generate;\x0a        output\x0a\x0aI am a disposable object";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generate",
+protocol: 'protocol',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+globals.HLInitializeGenerator.superclass.fn.prototype._generate.apply(_st(self), []);
+$1=_st(self["@output"])._targetClass();
+_st($1)._initializeSourceCodesWith_(self);
+$2=_st($1)._initializeProtocolWith_(self);
+return self}, function($ctx1) {$ctx1.fill(self,"generate",{},globals.HLInitializeGenerator)})},
+args: [],
+source: "generate\x0a\x09super generate.\x0a\x09\x0a\x09output targetClass \x0a\x09\x09initializeSourceCodesWith: self;\x0a\x09\x09initializeProtocolWith: self",
+messageSends: ["generate", "initializeSourceCodesWith:", "targetClass", "initializeProtocolWith:"],
+referencedClasses: []
+}),
+globals.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "generateInitializeCodeForObject",
+protocol: 'private',
+fn: function (){
+var self=this;
+function $String(){return globals.String||(typeof String=="undefined"?nil:String)}
+return smalltalk.withContext(function($ctx1) { 
+var $3,$2,$4,$5,$6,$7,$8,$1;
+$1=_st($String())._streamContents_((function(str){
+var instVars,size;
+return smalltalk.withContext(function($ctx2) {
+instVars=_st(_st(_st(self["@output"])._targetClass())._instanceVariableNames())._sorted();
+instVars;
+size=_st(instVars)._size();
+size;
+_st(str).__lt_lt("initialize");
+$ctx2.sendIdx["<<"]=1;
+$3=_st(str)._cr();
+$ctx2.sendIdx["cr"]=1;
+$2=_st($3)._tab();
+$ctx2.sendIdx["tab"]=1;
+_st($2).__lt_lt("super initialize.");
+$ctx2.sendIdx["<<"]=2;
+$4=_st($2)._cr();
+$ctx2.sendIdx["cr"]=2;
+$4;
+$5=_st(str)._cr();
+$ctx2.sendIdx["cr"]=3;
+_st($5)._tab();
+$ctx2.sendIdx["tab"]=2;
+return _st(instVars)._withIndexDo_((function(name,index){
+return smalltalk.withContext(function($ctx3) {
+$6=_st(index).__tild_eq((1));
+$ctx3.sendIdx["~="]=1;
+if(smalltalk.assert($6)){
+_st(_st(str)._cr())._tab();
+};
+$7=_st(str).__lt_lt(name);
+$ctx3.sendIdx["<<"]=4;
+_st($7).__lt_lt(" := nil");
+$ctx3.sendIdx["<<"]=3;
+$8=_st(index).__tild_eq(size);
+if(smalltalk.assert($8)){
+return _st(str).__lt_lt(".");
+};
+}, function($ctx3) {$ctx3.fillBlock({name:name,index:index},$ctx2,2)})}));
+}, function($ctx2) {$ctx2.fillBlock({str:str,instVars:instVars,size:size},$ctx1,1)})}));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"generateInitializeCodeForObject",{},globals.HLInitializeGenerator)})},
+args: [],
+source: "generateInitializeCodeForObject\x09\x0a\x09^ String streamContents: [ :str || instVars size |\x0a\x09\x09instVars := output targetClass instanceVariableNames sorted.\x0a\x09\x09size := instVars size.\x0a\x09\x09str << 'initialize'.\x0a\x09\x09str cr tab << 'super initialize.';cr.\x0a\x09\x09str cr tab.\x0a\x09\x09instVars withIndexDo: [ :name :index |\x0a\x09\x09\x09index ~= 1 ifTrue: [ str cr tab ].\x0a\x09\x09\x09str << name << ' := nil'.\x0a\x09\x09\x09index ~= size ifTrue: [ str << '.' ] ] ].",
+messageSends: ["streamContents:", "sorted", "instanceVariableNames", "targetClass", "size", "<<", "tab", "cr", "withIndexDo:", "ifTrue:", "~="],
+referencedClasses: ["String"]
+}),
+globals.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._addSourceCode_(self._initializeMethodForObject());
+return self}, function($ctx1) {$ctx1.fill(self,"initializeForObject",{},globals.HLInitializeGenerator)})},
+args: [],
+source: "initializeForObject\x0a\x09output addSourceCode: self initializeMethodForObject",
+messageSends: ["addSourceCode:", "initializeMethodForObject"],
+referencedClasses: []
+}),
+globals.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeMethodForObject",
+protocol: 'private',
+fn: function (){
+var self=this;
+function $HLMethodSourceCode(){return globals.HLMethodSourceCode||(typeof HLMethodSourceCode=="undefined"?nil:HLMethodSourceCode)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=_st($HLMethodSourceCode())._new();
+_st($2)._selector_("initialize");
+_st($2)._sourceCode_(self._generateInitializeCodeForObject());
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"initializeMethodForObject",{},globals.HLInitializeGenerator)})},
+args: [],
+source: "initializeMethodForObject\x09\x0a\x09^ HLMethodSourceCode new\x0a\x09\x09selector: 'initialize';\x0a\x09\x09sourceCode: self generateInitializeCodeForObject;\x0a\x09\x09yourself",
+messageSends: ["selector:", "new", "sourceCode:", "generateInitializeCodeForObject", "yourself"],
+referencedClasses: ["HLMethodSourceCode"]
+}),
+globals.HLInitializeGenerator);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initializeProtocolForObject",
+protocol: 'double-dispatch',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@output"])._protocol_("initialization");
+return self}, function($ctx1) {$ctx1.fill(self,"initializeProtocolForObject",{},globals.HLInitializeGenerator)})},
+args: [],
+source: "initializeProtocolForObject\x0a\x09output protocol: 'initialization'",
+messageSends: ["protocol:"],
+referencedClasses: []
+}),
+globals.HLInitializeGenerator);
+
+
+
+smalltalk.addClass('HLMethodSourceCode', globals.Object, ['selector', 'sourceCode'], 'Helios-Helpers');
+globals.HLMethodSourceCode.comment="I am a simple data object keeping track of the information about a method that will be compiled at the end of the generation process";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selector",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@selector"];
+return $1;
+},
+args: [],
+source: "selector\x0a\x09^ selector",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLMethodSourceCode);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selector:",
+protocol: 'accessing',
+fn: function (aSelector){
+var self=this;
+self["@selector"]=aSelector;
+return self},
+args: ["aSelector"],
+source: "selector: aSelector\x0a\x09selector := aSelector",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLMethodSourceCode);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCode",
+protocol: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+$1=self["@sourceCode"];
+return $1;
+},
+args: [],
+source: "sourceCode\x0a\x09^ sourceCode",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLMethodSourceCode);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "sourceCode:",
+protocol: 'accessing',
+fn: function (aString){
+var self=this;
+self["@sourceCode"]=aString;
+return self},
+args: ["aString"],
+source: "sourceCode: aString\x0a\x09sourceCode := aString",
+messageSends: [],
+referencedClasses: []
+}),
+globals.HLMethodSourceCode);
+
+
+});

File diff suppressed because it is too large
+ 233 - 277
js/Helios-Inspector.js


File diff suppressed because it is too large
+ 195 - 191
js/Helios-KeyBindings.js


+ 188 - 129
js/Helios-Layout.js

@@ -1,12 +1,12 @@
-define("amber_core/Helios-Layout", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Helios-Core", "amber_core/Canvas", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Layout", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Helios-Core", "amber_core/Canvas", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Layout');
 smalltalk.packages["Helios-Layout"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLContainer', smalltalk.HLWidget, ['splitter'], 'Helios-Layout');
+smalltalk.addClass('HLContainer', globals.HLWidget, ['splitter'], 'Helios-Layout');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "renderOn:",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -14,53 +14,51 @@ var $1,$2;
 $1=_st(html)._div();
 _st($1)._class_("tool_container");
 $2=_st($1)._with_(self._splitter());
-return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.HLContainer)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},globals.HLContainer)})},
 args: ["html"],
 source: "renderOn: html\x0a\x09html div \x0a    \x09class: 'tool_container'; \x0a        with: self splitter",
 messageSends: ["class:", "div", "with:", "splitter"],
 referencedClasses: []
 }),
-smalltalk.HLContainer);
+globals.HLContainer);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "splitter",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@splitter"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"splitter",{},smalltalk.HLContainer)})},
+},
 args: [],
 source: "splitter\x0a\x09^ splitter",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLContainer);
+globals.HLContainer);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "splitter:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aSplitter){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@splitter"]=aSplitter;
-return self}, function($ctx1) {$ctx1.fill(self,"splitter:",{aSplitter:aSplitter},smalltalk.HLContainer)})},
+return self},
 args: ["aSplitter"],
 source: "splitter: aSplitter\x0a\x09splitter := aSplitter",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLContainer);
+globals.HLContainer);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "with:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (aSplitter){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -70,201 +68,201 @@ _st($2)._splitter_(aSplitter);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"with:",{aSplitter:aSplitter},smalltalk.HLContainer.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"with:",{aSplitter:aSplitter},globals.HLContainer.klass)})},
 args: ["aSplitter"],
 source: "with: aSplitter\x0a\x09^ self new \x0a    \x09splitter: aSplitter; \x0a        yourself",
 messageSends: ["splitter:", "new", "yourself"],
 referencedClasses: []
 }),
-smalltalk.HLContainer.klass);
+globals.HLContainer.klass);
 
 
-smalltalk.addClass('HLSplitter', smalltalk.Widget, ['firstWidget', 'secondWidget', 'firstPane', 'secondPane', 'splitter'], 'Helios-Layout');
+smalltalk.addClass('HLSplitter', globals.Widget, ['firstWidget', 'secondWidget', 'firstPane', 'secondPane', 'splitter'], 'Helios-Layout');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "cssClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "splitter";
-}, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLSplitter)})},
+},
 args: [],
 source: "cssClass\x0a\x09^ 'splitter'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "firstWidget",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@firstWidget"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"firstWidget",{},smalltalk.HLSplitter)})},
+},
 args: [],
 source: "firstWidget\x0a\x09^ firstWidget",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "firstWidget:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aWidget){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@firstWidget"]=aWidget;
-return self}, function($ctx1) {$ctx1.fill(self,"firstWidget:",{aWidget:aWidget},smalltalk.HLSplitter)})},
+return self},
 args: ["aWidget"],
 source: "firstWidget: aWidget\x0a\x09firstWidget := aWidget",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isHeliosSplitter",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return true;
-}, function($ctx1) {$ctx1.fill(self,"isHeliosSplitter",{},smalltalk.HLSplitter)})},
+},
 args: [],
 source: "isHeliosSplitter\x0a\x09^ true",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "panesCssClass",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "panes";
-}, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},smalltalk.HLSplitter)})},
+},
 args: [],
 source: "panesCssClass\x0a\x09^ 'panes'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "renderOn:",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$3,$4,$5,$6,$2;
+var $1,$3,$4,$5,$6,$7,$2;
 $1=_st(html)._div();
+$ctx1.sendIdx["div"]=1;
 _st($1)._class_(self._panesCssClass());
+$ctx1.sendIdx["class:"]=1;
 $2=_st($1)._with_((function(){
 return smalltalk.withContext(function($ctx2) {
 $3=_st(html)._div();
+$ctx2.sendIdx["div"]=2;
 _st($3)._class_("pane");
+$ctx2.sendIdx["class:"]=2;
 $4=_st($3)._with_(self._firstWidget());
+$ctx2.sendIdx["with:"]=2;
 self["@firstPane"]=$4;
 self["@firstPane"];
-self["@splitter"]=_st(_st(html)._div())._class_(self._cssClass());
-self["@splitter"];
 $5=_st(html)._div();
-_st($5)._class_("pane");
-$6=_st($5)._with_(self._secondWidget());
-self["@secondPane"]=$6;
+$ctx2.sendIdx["div"]=3;
+self["@splitter"]=_st($5)._class_(self._cssClass());
+$ctx2.sendIdx["class:"]=3;
+self["@splitter"];
+$6=_st(html)._div();
+_st($6)._class_("pane");
+$7=_st($6)._with_(self._secondWidget());
+self["@secondPane"]=$7;
 return self["@secondPane"];
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+$ctx1.sendIdx["with:"]=1;
 self._setupSplitter();
-return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.HLSplitter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},globals.HLSplitter)})},
 args: ["html"],
 source: "renderOn: html\x0a\x09html div class: self panesCssClass; with: [\x0a\x09\x09firstPane := html div class: 'pane'; with: self firstWidget.\x0a    \x09splitter := html div class: self cssClass.\x0a    \x09secondPane := html div class: 'pane'; with: self secondWidget ].\x0a        \x0a\x09self setupSplitter",
 messageSends: ["class:", "div", "panesCssClass", "with:", "firstWidget", "cssClass", "secondWidget", "setupSplitter"],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "resize",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self}, function($ctx1) {$ctx1.fill(self,"resize",{},smalltalk.HLSplitter)})},
+return self},
 args: [],
 source: "resize",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "secondWidget",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@secondWidget"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"secondWidget",{},smalltalk.HLSplitter)})},
+},
 args: [],
 source: "secondWidget\x0a\x09^ secondWidget",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "secondWidget:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aWidget){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@secondWidget"]=aWidget;
-return self}, function($ctx1) {$ctx1.fill(self,"secondWidget:",{aWidget:aWidget},smalltalk.HLSplitter)})},
+return self},
 args: ["aWidget"],
 source: "secondWidget: aWidget\x0a\x09secondWidget := aWidget",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setupSplitter",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self}, function($ctx1) {$ctx1.fill(self,"setupSplitter",{},smalltalk.HLSplitter)})},
+return self},
 args: [],
 source: "setupSplitter",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.HLSplitter);
+globals.HLSplitter);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "with:with:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (aWidget,anotherWidget){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -275,262 +273,323 @@ _st($2)._secondWidget_(anotherWidget);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"with:with:",{aWidget:aWidget,anotherWidget:anotherWidget},smalltalk.HLSplitter.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"with:with:",{aWidget:aWidget,anotherWidget:anotherWidget},globals.HLSplitter.klass)})},
 args: ["aWidget", "anotherWidget"],
 source: "with: aWidget with: anotherWidget\x0a\x09^ self new\x0a    \x09\x09firstWidget: aWidget;\x0a            secondWidget: anotherWidget;\x0a            yourself",
 messageSends: ["firstWidget:", "new", "secondWidget:", "yourself"],
 referencedClasses: []
 }),
-smalltalk.HLSplitter.klass);
+globals.HLSplitter.klass);
 
 
-smalltalk.addClass('HLHorizontalSplitter', smalltalk.HLSplitter, [], 'Helios-Layout');
+smalltalk.addClass('HLHorizontalSplitter', globals.HLSplitter, [], 'Helios-Layout');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "cssClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLHorizontalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" horizontal");
+$1=_st(globals.HLHorizontalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" horizontal");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLHorizontalSplitter)})},
+}, function($ctx1) {$ctx1.fill(self,"cssClass",{},globals.HLHorizontalSplitter)})},
 args: [],
 source: "cssClass\x0a\x09^ super cssClass, ' horizontal'",
 messageSends: [",", "cssClass"],
 referencedClasses: []
 }),
-smalltalk.HLHorizontalSplitter);
+globals.HLHorizontalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "panesCssClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLHorizontalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" horizontal");
+$1=_st(globals.HLHorizontalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" horizontal");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},smalltalk.HLHorizontalSplitter)})},
+}, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},globals.HLHorizontalSplitter)})},
 args: [],
 source: "panesCssClass\x0a\x09^ super panesCssClass, ' horizontal'",
 messageSends: [",", "panesCssClass"],
 referencedClasses: []
 }),
-smalltalk.HLHorizontalSplitter);
+globals.HLHorizontalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "resize",
-category: 'actions',
+protocol: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._resize_(_st(_st(self["@splitter"])._asJQuery())._css_("top"));
-return self}, function($ctx1) {$ctx1.fill(self,"resize",{},smalltalk.HLHorizontalSplitter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"resize",{},globals.HLHorizontalSplitter)})},
 args: [],
 source: "resize\x0a\x09self resize: (splitter asJQuery css: 'top')",
 messageSends: ["resize:", "css:", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.HLHorizontalSplitter);
+globals.HLHorizontalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "resize:",
-category: 'actions',
+protocol: 'actions',
 fn: function (anInteger){
 var self=this;
 var container,size,offset,percentage;
 return smalltalk.withContext(function($ctx1) { 
-container=_st(_st(self["@firstPane"])._asJQuery())._parent();
-offset=_st(_st(_st(self["@firstPane"])._asJQuery())._offset())._top();
+var $1,$3,$2,$6,$7,$5,$4,$8,$10,$9,$11,$14,$13,$12;
+$1=_st(self["@firstPane"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=1;
+container=_st($1)._parent();
+$3=_st(self["@firstPane"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=2;
+$2=_st($3)._offset();
+offset=_st($2)._top();
 size=_st(container)._height();
-percentage=_st(_st(_st(size).__minus(_st(anInteger).__minus(offset))).__slash(size)).__star((100));
+$6=size;
+$7=_st(anInteger).__minus(offset);
+$ctx1.sendIdx["-"]=2;
+$5=_st($6).__minus($7);
+$ctx1.sendIdx["-"]=1;
+$4=_st($5).__slash(size);
+percentage=_st($4).__star((100));
 percentage=(80)._min_(_st(percentage)._max_((20)));
-_st(_st(self["@firstPane"])._asJQuery())._css_put_("bottom",_st(_st(percentage)._asString()).__comma("%"));
-_st(_st(self["@splitter"])._asJQuery())._css_put_("top",_st(_st((100).__minus(percentage))._asString()).__comma("%"));
+$8=_st(self["@firstPane"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=3;
+$10=_st(percentage)._asString();
+$ctx1.sendIdx["asString"]=1;
+$9=_st($10).__comma("%");
+$ctx1.sendIdx[","]=1;
+_st($8)._css_put_("bottom",$9);
+$ctx1.sendIdx["css:put:"]=1;
+$11=_st(self["@splitter"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=4;
+$14=(100).__minus(percentage);
+$ctx1.sendIdx["-"]=3;
+$13=_st($14)._asString();
+$ctx1.sendIdx["asString"]=2;
+$12=_st($13).__comma("%");
+$ctx1.sendIdx[","]=2;
+_st($11)._css_put_("top",$12);
+$ctx1.sendIdx["css:put:"]=2;
 _st(_st(self["@secondPane"])._asJQuery())._css_put_("top",_st(_st((100).__minus(percentage))._asString()).__comma("%"));
-return self}, function($ctx1) {$ctx1.fill(self,"resize:",{anInteger:anInteger,container:container,size:size,offset:offset,percentage:percentage},smalltalk.HLHorizontalSplitter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"resize:",{anInteger:anInteger,container:container,size:size,offset:offset,percentage:percentage},globals.HLHorizontalSplitter)})},
 args: ["anInteger"],
 source: "resize: anInteger\x0a\x09| container size offset percentage |\x0a    \x0a    container := firstPane asJQuery parent.\x0a\x09offset := firstPane asJQuery offset top.\x0a    size := container height.\x0a\x09\x0a\x09percentage := (size - (anInteger - offset)) / size * 100.\x0a\x09percentage := 80 min: (percentage max: 20).\x0a\x09\x0a    firstPane asJQuery css: 'bottom' put: percentage asString, '%'.\x0a\x09\x0a\x09splitter asJQuery css: 'top' put: (100 - percentage) asString, '%'.\x0a\x09secondPane asJQuery css: 'top' put: (100 - percentage) asString, '%'",
 messageSends: ["parent", "asJQuery", "top", "offset", "height", "*", "/", "-", "min:", "max:", "css:put:", ",", "asString"],
 referencedClasses: []
 }),
-smalltalk.HLHorizontalSplitter);
+globals.HLHorizontalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setupSplitter",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._from_(["axis".__minus_gt("y"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
+var $1;
+$1=_st(self["@splitter"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=1;
+_st($1)._draggable_(globals.HashedCollection._newFromPairs_(["axis","y","containment",_st(_st(self["@splitter"])._asJQuery())._parent(),"helper","clone","start",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})})),"drag".__minus_gt((function(e,ui){
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})}),"drag",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._resize_(_st(_st(ui)._offset())._top());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})}))]));
-return self}, function($ctx1) {$ctx1.fill(self,"setupSplitter",{},smalltalk.HLHorizontalSplitter)})},
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})})]));
+return self}, function($ctx1) {$ctx1.fill(self,"setupSplitter",{},globals.HLHorizontalSplitter)})},
 args: [],
 source: "setupSplitter\x0a\x09splitter asJQuery draggable: #{ \x0a    \x09'axis' -> 'y'. \x0a        'containment' -> splitter asJQuery parent.\x0a        'helper' -> 'clone'.\x0a        'start' -> [ :e :ui | self startResizing: ui helper ].\x0a        'drag' -> [ :e :ui | self resize: ui offset top ] }",
-messageSends: ["draggable:", "asJQuery", "->", "parent", "startResizing:", "helper", "resize:", "top", "offset"],
+messageSends: ["draggable:", "asJQuery", "parent", "startResizing:", "helper", "resize:", "top", "offset"],
 referencedClasses: []
 }),
-smalltalk.HLHorizontalSplitter);
+globals.HLHorizontalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "startResizing:",
-category: 'actions',
+protocol: 'actions',
 fn: function (aSplitter){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(aSplitter)._width_(_st(_st(self["@splitter"])._asJQuery())._width());
-return self}, function($ctx1) {$ctx1.fill(self,"startResizing:",{aSplitter:aSplitter},smalltalk.HLHorizontalSplitter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"startResizing:",{aSplitter:aSplitter},globals.HLHorizontalSplitter)})},
 args: ["aSplitter"],
 source: "startResizing: aSplitter\x0a\x09aSplitter width: splitter asJQuery width",
 messageSends: ["width:", "width", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.HLHorizontalSplitter);
+globals.HLHorizontalSplitter);
 
 
 
-smalltalk.addClass('HLVerticalSplitter', smalltalk.HLSplitter, [], 'Helios-Layout');
+smalltalk.addClass('HLVerticalSplitter', globals.HLSplitter, [], 'Helios-Layout');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "cssClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLVerticalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" vertical");
+$1=_st(globals.HLVerticalSplitter.superclass.fn.prototype._cssClass.apply(_st(self), [])).__comma(" vertical");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLVerticalSplitter)})},
+}, function($ctx1) {$ctx1.fill(self,"cssClass",{},globals.HLVerticalSplitter)})},
 args: [],
 source: "cssClass\x0a\x09^ super cssClass, ' vertical'",
 messageSends: [",", "cssClass"],
 referencedClasses: []
 }),
-smalltalk.HLVerticalSplitter);
+globals.HLVerticalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "panesCssClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(smalltalk.HLVerticalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" vertical");
+$1=_st(globals.HLVerticalSplitter.superclass.fn.prototype._panesCssClass.apply(_st(self), [])).__comma(" vertical");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},smalltalk.HLVerticalSplitter)})},
+}, function($ctx1) {$ctx1.fill(self,"panesCssClass",{},globals.HLVerticalSplitter)})},
 args: [],
 source: "panesCssClass\x0a\x09^ super panesCssClass, ' vertical'",
 messageSends: [",", "panesCssClass"],
 referencedClasses: []
 }),
-smalltalk.HLVerticalSplitter);
+globals.HLVerticalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "resize",
-category: 'actions',
+protocol: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._resize_(_st(_st(self["@splitter"])._asJQuery())._css_("left"));
-return self}, function($ctx1) {$ctx1.fill(self,"resize",{},smalltalk.HLVerticalSplitter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"resize",{},globals.HLVerticalSplitter)})},
 args: [],
 source: "resize\x0a\x09self resize: (splitter asJQuery css: 'left')",
 messageSends: ["resize:", "css:", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.HLVerticalSplitter);
+globals.HLVerticalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "resize:",
-category: 'actions',
+protocol: 'actions',
 fn: function (anInteger){
 var self=this;
 var container,size,offset,percentage;
 return smalltalk.withContext(function($ctx1) { 
-container=_st(_st(self["@firstPane"])._asJQuery())._parent();
-offset=_st(_st(_st(self["@firstPane"])._asJQuery())._offset())._left();
+var $1,$3,$2,$6,$7,$5,$4,$8,$10,$9,$11,$14,$13,$12;
+$1=_st(self["@firstPane"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=1;
+container=_st($1)._parent();
+$3=_st(self["@firstPane"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=2;
+$2=_st($3)._offset();
+offset=_st($2)._left();
 size=_st(container)._width();
-percentage=_st(_st(_st(size).__minus(_st(anInteger).__minus(offset))).__slash(size)).__star((100));
+$6=size;
+$7=_st(anInteger).__minus(offset);
+$ctx1.sendIdx["-"]=2;
+$5=_st($6).__minus($7);
+$ctx1.sendIdx["-"]=1;
+$4=_st($5).__slash(size);
+percentage=_st($4).__star((100));
 percentage=(80)._min_(_st(percentage)._max_((20)));
-_st(_st(self["@firstPane"])._asJQuery())._css_put_("right",_st(_st(percentage)._asString()).__comma("%"));
-_st(_st(self["@splitter"])._asJQuery())._css_put_("left",_st(_st((100).__minus(percentage))._asString()).__comma("%"));
+$8=_st(self["@firstPane"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=3;
+$10=_st(percentage)._asString();
+$ctx1.sendIdx["asString"]=1;
+$9=_st($10).__comma("%");
+$ctx1.sendIdx[","]=1;
+_st($8)._css_put_("right",$9);
+$ctx1.sendIdx["css:put:"]=1;
+$11=_st(self["@splitter"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=4;
+$14=(100).__minus(percentage);
+$ctx1.sendIdx["-"]=3;
+$13=_st($14)._asString();
+$ctx1.sendIdx["asString"]=2;
+$12=_st($13).__comma("%");
+$ctx1.sendIdx[","]=2;
+_st($11)._css_put_("left",$12);
+$ctx1.sendIdx["css:put:"]=2;
 _st(_st(self["@secondPane"])._asJQuery())._css_put_("left",_st(_st((100).__minus(percentage))._asString()).__comma("%"));
-return self}, function($ctx1) {$ctx1.fill(self,"resize:",{anInteger:anInteger,container:container,size:size,offset:offset,percentage:percentage},smalltalk.HLVerticalSplitter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"resize:",{anInteger:anInteger,container:container,size:size,offset:offset,percentage:percentage},globals.HLVerticalSplitter)})},
 args: ["anInteger"],
 source: "resize: anInteger\x0a\x09| container size offset percentage |\x0a    \x0a    container := firstPane asJQuery parent.\x0a\x09offset := firstPane asJQuery offset left.\x0a    size := container width.\x0a\x09\x0a\x09percentage := (size - (anInteger - offset)) / size * 100.\x0a\x09percentage := 80 min: (percentage max: 20).\x0a\x09\x0a    firstPane asJQuery css: 'right' put: percentage asString, '%'.\x0a\x09\x0a\x09splitter asJQuery css: 'left' put: (100 - percentage) asString, '%'.\x0a\x09secondPane asJQuery css: 'left' put: (100 - percentage) asString, '%'",
 messageSends: ["parent", "asJQuery", "left", "offset", "width", "*", "/", "-", "min:", "max:", "css:put:", ",", "asString"],
 referencedClasses: []
 }),
-smalltalk.HLVerticalSplitter);
+globals.HLVerticalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setupSplitter",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._from_(["axis".__minus_gt("x"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
+var $1;
+$1=_st(self["@splitter"])._asJQuery();
+$ctx1.sendIdx["asJQuery"]=1;
+_st($1)._draggable_(globals.HashedCollection._newFromPairs_(["axis","x","containment",_st(_st(self["@splitter"])._asJQuery())._parent(),"helper","clone","start",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})})),"drag".__minus_gt((function(e,ui){
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,1)})}),"drag",(function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._resize_(_st(_st(ui)._offset())._left());
-}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})}))]));
-return self}, function($ctx1) {$ctx1.fill(self,"setupSplitter",{},smalltalk.HLVerticalSplitter)})},
+}, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1,2)})})]));
+return self}, function($ctx1) {$ctx1.fill(self,"setupSplitter",{},globals.HLVerticalSplitter)})},
 args: [],
 source: "setupSplitter\x0a\x09splitter asJQuery draggable: #{ \x0a    \x09'axis' -> 'x'. \x0a        'containment' -> splitter asJQuery parent.\x0a        'helper' -> 'clone'.\x0a        'start' -> [ :e :ui | self startResizing: ui helper ].\x0a        'drag' -> [ :e :ui | self resize: (ui offset left) ] }",
-messageSends: ["draggable:", "asJQuery", "->", "parent", "startResizing:", "helper", "resize:", "left", "offset"],
+messageSends: ["draggable:", "asJQuery", "parent", "startResizing:", "helper", "resize:", "left", "offset"],
 referencedClasses: []
 }),
-smalltalk.HLVerticalSplitter);
+globals.HLVerticalSplitter);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "startResizing:",
-category: 'actions',
+protocol: 'actions',
 fn: function (aSplitter){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(aSplitter)._height_(_st(_st(self["@splitter"])._asJQuery())._height());
-return self}, function($ctx1) {$ctx1.fill(self,"startResizing:",{aSplitter:aSplitter},smalltalk.HLVerticalSplitter)})},
+return self}, function($ctx1) {$ctx1.fill(self,"startResizing:",{aSplitter:aSplitter},globals.HLVerticalSplitter)})},
 args: ["aSplitter"],
 source: "startResizing: aSplitter\x0a\x09aSplitter height: splitter asJQuery height",
 messageSends: ["height:", "height", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.HLVerticalSplitter);
+globals.HLVerticalSplitter);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isHeliosSplitter",
-category: '*Helios-Layout',
+protocol: '*Helios-Layout',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return false;
-}, function($ctx1) {$ctx1.fill(self,"isHeliosSplitter",{},smalltalk.Object)})},
+},
 args: [],
 source: "isHeliosSplitter\x0a\x09^ false",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Object);
+globals.Object);
 
 });

File diff suppressed because it is too large
+ 189 - 222
js/Helios-References.js


+ 55 - 53
js/Helios-Transcript.js

@@ -1,63 +1,63 @@
-define("amber_core/Helios-Transcript", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Helios-Core", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Transcript", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Helios-Core", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Transcript');
 smalltalk.packages["Helios-Transcript"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLTranscript', smalltalk.HLWidget, ['textarea'], 'Helios-Transcript');
-smalltalk.HLTranscript.comment="I am a widget responsible for displaying transcript contents.\x0a\x0a## Transcript API\x0a\x0a    Transcript \x0a        show: 'hello world';\x0a        cr;\x0a        show: anObject.\x0a\x0a    Transcript clear.\x0a\x0aSee the `Transcript` class.";
+smalltalk.addClass('HLTranscript', globals.HLWidget, ['textarea'], 'Helios-Transcript');
+globals.HLTranscript.comment="I am a widget responsible for displaying transcript contents.\x0a\x0a## Transcript API\x0a\x0a    Transcript \x0a        show: 'hello world';\x0a        cr;\x0a        show: anObject.\x0a\x0a    Transcript clear.\x0a\x0aSee the `Transcript` class.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "clear",
-category: 'actions',
+protocol: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(_st(self["@textarea"])._asJQuery())._text_("");
-return self}, function($ctx1) {$ctx1.fill(self,"clear",{},smalltalk.HLTranscript)})},
+return self}, function($ctx1) {$ctx1.fill(self,"clear",{},globals.HLTranscript)})},
 args: [],
 source: "clear\x0a\x09textarea asJQuery text: ''",
 messageSends: ["text:", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.HLTranscript);
+globals.HLTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLTranscript.superclass.fn.prototype._initialize.apply(_st(self), []);
+globals.HLTranscript.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._register();
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLTranscript)})},
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.HLTranscript)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09self register",
 messageSends: ["initialize", "register"],
 referencedClasses: []
 }),
-smalltalk.HLTranscript);
+globals.HLTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "register",
-category: 'registration',
+protocol: 'registration',
 fn: function (){
 var self=this;
-function $HLTranscriptHandler(){return smalltalk.HLTranscriptHandler||(typeof HLTranscriptHandler=="undefined"?nil:HLTranscriptHandler)}
+function $HLTranscriptHandler(){return globals.HLTranscriptHandler||(typeof HLTranscriptHandler=="undefined"?nil:HLTranscriptHandler)}
 return smalltalk.withContext(function($ctx1) { 
 _st($HLTranscriptHandler())._register_(self);
-return self}, function($ctx1) {$ctx1.fill(self,"register",{},smalltalk.HLTranscript)})},
+return self}, function($ctx1) {$ctx1.fill(self,"register",{},globals.HLTranscript)})},
 args: [],
 source: "register\x0a\x09HLTranscriptHandler register: self",
 messageSends: ["register:"],
 referencedClasses: ["HLTranscriptHandler"]
 }),
-smalltalk.HLTranscript);
+globals.HLTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "renderOn:",
-category: 'rendering',
+protocol: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -69,18 +69,18 @@ return smalltalk.withContext(function($ctx2) {
 self["@textarea"]=_st(html)._textarea();
 return self["@textarea"];
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},smalltalk.HLTranscript)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderOn:",{html:html},globals.HLTranscript)})},
 args: ["html"],
 source: "renderOn: html\x0a\x09html div\x0a\x09\x09class: 'transcript';\x0a\x09\x09with: [ textarea := html textarea ]",
 messageSends: ["class:", "div", "with:", "textarea"],
 referencedClasses: []
 }),
-smalltalk.HLTranscript);
+globals.HLTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "show:",
-category: 'actions',
+protocol: 'actions',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -91,42 +91,42 @@ $1;
 } else {
 _st(_st(self["@textarea"])._asJQuery())._append_(_st(aString)._asString());
 };
-return self}, function($ctx1) {$ctx1.fill(self,"show:",{aString:aString},smalltalk.HLTranscript)})},
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{aString:aString},globals.HLTranscript)})},
 args: ["aString"],
 source: "show: aString\x0a\x09textarea ifNotNil: [\x0a \x09\x09textarea asJQuery append: aString asString ]",
 messageSends: ["ifNotNil:", "append:", "asJQuery", "asString"],
 referencedClasses: []
 }),
-smalltalk.HLTranscript);
+globals.HLTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "unregister",
-category: 'registration',
+protocol: 'registration',
 fn: function (){
 var self=this;
-function $HLTranscriptHandler(){return smalltalk.HLTranscriptHandler||(typeof HLTranscriptHandler=="undefined"?nil:HLTranscriptHandler)}
+function $HLTranscriptHandler(){return globals.HLTranscriptHandler||(typeof HLTranscriptHandler=="undefined"?nil:HLTranscriptHandler)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLTranscript.superclass.fn.prototype._unregister.apply(_st(self), []);
+globals.HLTranscript.superclass.fn.prototype._unregister.apply(_st(self), []);
 _st($HLTranscriptHandler())._unregister_(self);
-return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},smalltalk.HLTranscript)})},
+return self}, function($ctx1) {$ctx1.fill(self,"unregister",{},globals.HLTranscript)})},
 args: [],
 source: "unregister\x0a\x09super unregister.\x0a\x09HLTranscriptHandler unregister: self",
 messageSends: ["unregister", "unregister:"],
 referencedClasses: ["HLTranscriptHandler"]
 }),
-smalltalk.HLTranscript);
+globals.HLTranscript);
 
 
 
-smalltalk.addClass('HLTranscriptHandler', smalltalk.Object, [], 'Helios-Transcript');
-smalltalk.HLTranscriptHandler.comment="I handle transcript events, dispatching them to all instances of `HLTranscript`.\x0a\x0a## API\x0a\x0aOn class initialization I am automatically registered as the current transcript.";
+smalltalk.addClass('HLTranscriptHandler', globals.Object, [], 'Helios-Transcript');
+globals.HLTranscriptHandler.comment="I handle transcript events, dispatching them to all instances of `HLTranscript`.\x0a\x0a## API\x0a\x0aOn class initialization I am automatically registered as the current transcript.";
 
-smalltalk.HLTranscriptHandler.klass.iVarNames = ['transcripts'];
+globals.HLTranscriptHandler.klass.iVarNames = ['transcripts'];
 smalltalk.addMethod(
 smalltalk.method({
 selector: "clear",
-category: 'registration',
+protocol: 'printing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -134,51 +134,53 @@ _st(self._transcripts())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._clear();
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"clear",{},smalltalk.HLTranscriptHandler.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"clear",{},globals.HLTranscriptHandler.klass)})},
 args: [],
 source: "clear\x0a\x09self transcripts do: [ :each |\x0a\x09\x09each clear ]",
 messageSends: ["do:", "transcripts", "clear"],
 referencedClasses: []
 }),
-smalltalk.HLTranscriptHandler.klass);
+globals.HLTranscriptHandler.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "initialize",
-category: 'initialization',
+selector: "cr",
+protocol: 'printing',
 fn: function (){
 var self=this;
-function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
 return smalltalk.withContext(function($ctx1) { 
-_st($Transcript())._register_(self);
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLTranscriptHandler.klass)})},
+_st(self._transcripts())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(each)._cr();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"cr",{},globals.HLTranscriptHandler.klass)})},
 args: [],
-source: "initialize\x0a\x09Transcript register: self",
-messageSends: ["register:"],
-referencedClasses: ["Transcript"]
+source: "cr\x0a\x09self transcripts do: [ :each | each cr ]",
+messageSends: ["do:", "transcripts", "cr"],
+referencedClasses: []
 }),
-smalltalk.HLTranscriptHandler.klass);
+globals.HLTranscriptHandler.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "register:",
-category: 'registration',
+protocol: 'registration',
 fn: function (aTranscript){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._transcripts())._add_(aTranscript);
-return self}, function($ctx1) {$ctx1.fill(self,"register:",{aTranscript:aTranscript},smalltalk.HLTranscriptHandler.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"register:",{aTranscript:aTranscript},globals.HLTranscriptHandler.klass)})},
 args: ["aTranscript"],
 source: "register: aTranscript\x0a\x09self transcripts add: aTranscript",
 messageSends: ["add:", "transcripts"],
 referencedClasses: []
 }),
-smalltalk.HLTranscriptHandler.klass);
+globals.HLTranscriptHandler.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "show:",
-category: 'registration',
+protocol: 'printing',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -186,21 +188,21 @@ _st(self._transcripts())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._show_(aString);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"show:",{aString:aString},smalltalk.HLTranscriptHandler.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{aString:aString},globals.HLTranscriptHandler.klass)})},
 args: ["aString"],
 source: "show: aString\x0a\x09self transcripts do: [ :each |\x0a\x09\x09each show: aString ]",
 messageSends: ["do:", "transcripts", "show:"],
 referencedClasses: []
 }),
-smalltalk.HLTranscriptHandler.klass);
+globals.HLTranscriptHandler.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "transcripts",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+function $OrderedCollection(){return globals.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
 $2=self["@transcripts"];
@@ -211,28 +213,28 @@ $1=self["@transcripts"];
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"transcripts",{},smalltalk.HLTranscriptHandler.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"transcripts",{},globals.HLTranscriptHandler.klass)})},
 args: [],
 source: "transcripts\x0a\x09^ transcripts ifNil: [ transcripts := OrderedCollection new ]",
 messageSends: ["ifNil:", "new"],
 referencedClasses: ["OrderedCollection"]
 }),
-smalltalk.HLTranscriptHandler.klass);
+globals.HLTranscriptHandler.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "unregister:",
-category: 'registration',
+protocol: 'registration',
 fn: function (aTranscript){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self._transcripts())._remove_(aTranscript);
-return self}, function($ctx1) {$ctx1.fill(self,"unregister:",{aTranscript:aTranscript},smalltalk.HLTranscriptHandler.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"unregister:",{aTranscript:aTranscript},globals.HLTranscriptHandler.klass)})},
 args: ["aTranscript"],
 source: "unregister: aTranscript\x0a\x09self transcripts remove: aTranscript",
 messageSends: ["remove:", "transcripts"],
 referencedClasses: []
 }),
-smalltalk.HLTranscriptHandler.klass);
+globals.HLTranscriptHandler.klass);
 
 });

+ 12 - 8
js/Helios-Workspace-Tests.js

@@ -1,26 +1,30 @@
-define("amber_core/Helios-Workspace-Tests", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/SUnit"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Workspace-Tests", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/SUnit"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Helios-Workspace-Tests');
 smalltalk.packages["Helios-Workspace-Tests"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('HLCodeWidgetTest', smalltalk.TestCase, [], 'Helios-Workspace-Tests');
+smalltalk.addClass('HLCodeWidgetTest', globals.TestCase, [], 'Helios-Workspace-Tests');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testKeyMap",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
-function $HLCodeWidget(){return smalltalk.HLCodeWidget||(typeof HLCodeWidget=="undefined"?nil:HLCodeWidget)}
-function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
+function $HLCodeWidget(){return globals.HLCodeWidget||(typeof HLCodeWidget=="undefined"?nil:HLCodeWidget)}
+function $HashedCollection(){return globals.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-self._assert_(_st(_st($HLCodeWidget())._pcKeyMap())._isKindOf_($HashedCollection()));
+var $1;
+$1=_st(_st($HLCodeWidget())._pcKeyMap())._isKindOf_($HashedCollection());
+$ctx1.sendIdx["isKindOf:"]=1;
+self._assert_($1);
+$ctx1.sendIdx["assert:"]=1;
 self._assert_(_st(_st($HLCodeWidget())._macKeyMap())._isKindOf_($HashedCollection()));
-return self}, function($ctx1) {$ctx1.fill(self,"testKeyMap",{},smalltalk.HLCodeWidgetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testKeyMap",{},globals.HLCodeWidgetTest)})},
 args: [],
 source: "testKeyMap\x0a\x09\x22Key maps are a collection of associations.\x22\x0a\x09self assert: (HLCodeWidget pcKeyMap isKindOf: HashedCollection).\x0a\x09self assert: (HLCodeWidget macKeyMap isKindOf: HashedCollection)",
 messageSends: ["assert:", "isKindOf:", "pcKeyMap", "macKeyMap"],
 referencedClasses: ["HLCodeWidget", "HashedCollection"]
 }),
-smalltalk.HLCodeWidgetTest);
+globals.HLCodeWidgetTest);
 
 
 });

File diff suppressed because it is too large
+ 313 - 237
js/Helios-Workspace.js


File diff suppressed because it is too large
+ 217 - 188
js/IDE.js


+ 215 - 233
js/Kernel-Announcements.js

@@ -1,47 +1,45 @@
-define("amber_core/Kernel-Announcements", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Kernel-Announcements", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Kernel-Announcements');
 smalltalk.packages["Kernel-Announcements"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('AnnouncementSubscription', smalltalk.Object, ['valuable', 'announcementClass'], 'Kernel-Announcements');
-smalltalk.AnnouncementSubscription.comment="I am a single entry in a subscription registry of an `Announcer`.\x0aSeveral subscriptions by the same object is possible.";
+smalltalk.addClass('AnnouncementSubscription', globals.Object, ['valuable', 'announcementClass'], 'Kernel-Announcements');
+globals.AnnouncementSubscription.comment="I am a single entry in a subscription registry of an `Announcer`.\x0aSeveral subscriptions by the same object is possible.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "announcementClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@announcementClass"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"announcementClass",{},smalltalk.AnnouncementSubscription)})},
+},
 args: [],
 source: "announcementClass\x0a\x09^ announcementClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "announcementClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@announcementClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"announcementClass:",{aClass:aClass},smalltalk.AnnouncementSubscription)})},
+return self},
 args: ["aClass"],
 source: "announcementClass: aClass\x0a\x09announcementClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "block",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -49,35 +47,35 @@ var $1;
 self._deprecatedAPI();
 $1=self._valuable();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"block",{},smalltalk.AnnouncementSubscription)})},
+}, function($ctx1) {$ctx1.fill(self,"block",{},globals.AnnouncementSubscription)})},
 args: [],
 source: "block\x0a\x09\x22Use #valuable instead\x22\x0a\x09\x0a\x09self deprecatedAPI.\x0a\x09^ self valuable",
 messageSends: ["deprecatedAPI", "valuable"],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "block:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aValuable){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._deprecatedAPI();
 self._valuable_(aValuable);
-return self}, function($ctx1) {$ctx1.fill(self,"block:",{aValuable:aValuable},smalltalk.AnnouncementSubscription)})},
+return self}, function($ctx1) {$ctx1.fill(self,"block:",{aValuable:aValuable},globals.AnnouncementSubscription)})},
 args: ["aValuable"],
 source: "block: aValuable\x0a\x09\x22Use #valuable instead\x22\x0a\x09\x0a\x09self deprecatedAPI.\x0a\x09self valuable: aValuable",
 messageSends: ["deprecatedAPI", "valuable:"],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "deliver:",
-category: 'announcing',
+protocol: 'announcing',
 fn: function (anAnnouncement){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -86,100 +84,103 @@ $1=self._handlesAnnouncement_(anAnnouncement);
 if(smalltalk.assert($1)){
 _st(self._valuable())._value_(anAnnouncement);
 };
-return self}, function($ctx1) {$ctx1.fill(self,"deliver:",{anAnnouncement:anAnnouncement},smalltalk.AnnouncementSubscription)})},
+return self}, function($ctx1) {$ctx1.fill(self,"deliver:",{anAnnouncement:anAnnouncement},globals.AnnouncementSubscription)})},
 args: ["anAnnouncement"],
-source: "deliver: anAnnouncement\x0a\x09(self handlesAnnouncement: anAnnouncement)\x0a\x09\x09ifTrue: [self valuable value: anAnnouncement]",
+source: "deliver: anAnnouncement\x0a\x09(self handlesAnnouncement: anAnnouncement)\x0a\x09\x09ifTrue: [ self valuable value: anAnnouncement ]",
 messageSends: ["ifTrue:", "handlesAnnouncement:", "value:", "valuable"],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "handlesAnnouncement:",
-category: 'announcing',
+protocol: 'announcing',
 fn: function (anAnnouncement){
 var self=this;
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=_st(_st($Smalltalk())._current())._at_(_st(self._announcementClass())._name());
+var $3,$4,$2,$1;
+$3=_st($Smalltalk())._globals();
+$ctx1.sendIdx["globals"]=1;
+$4=_st(self._announcementClass())._name();
+$ctx1.sendIdx["name"]=1;
+$2=_st($3)._at_($4);
+$ctx1.sendIdx["at:"]=1;
 if(($receiver = $2) == nil || $receiver == null){
 return false;
 } else {
 var class_;
 class_=$receiver;
-$1=_st(_st(_st($Smalltalk())._current())._at_(_st(_st(_st(anAnnouncement)._class())._theNonMetaClass())._name()))._includesBehavior_(class_);
+$1=_st(_st(_st($Smalltalk())._globals())._at_(_st(_st(_st(anAnnouncement)._class())._theNonMetaClass())._name()))._includesBehavior_(class_);
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"handlesAnnouncement:",{anAnnouncement:anAnnouncement},smalltalk.AnnouncementSubscription)})},
+}, function($ctx1) {$ctx1.fill(self,"handlesAnnouncement:",{anAnnouncement:anAnnouncement},globals.AnnouncementSubscription)})},
 args: ["anAnnouncement"],
-source: "handlesAnnouncement: anAnnouncement\x0a\x09\x22anAnnouncement might be announced from within another Amber environment\x22\x0a\x09\x0a\x09^ (Smalltalk current at: self announcementClass name)\x0a\x09\x09ifNil: [ ^ false ]\x0a\x09\x09ifNotNil: [ :class |\x0a\x09\x09(Smalltalk current at: anAnnouncement class theNonMetaClass name) includesBehavior: class ]",
-messageSends: ["ifNil:ifNotNil:", "at:", "current", "name", "announcementClass", "includesBehavior:", "theNonMetaClass", "class"],
+source: "handlesAnnouncement: anAnnouncement\x0a\x09\x22anAnnouncement might be announced from within another Amber environment\x22\x0a\x09\x0a\x09^ (Smalltalk globals at: self announcementClass name)\x0a\x09\x09ifNil: [ ^ false ]\x0a\x09\x09ifNotNil: [ :class |\x0a\x09\x09(Smalltalk globals at: anAnnouncement class theNonMetaClass name) includesBehavior: class ]",
+messageSends: ["ifNil:ifNotNil:", "at:", "globals", "name", "announcementClass", "includesBehavior:", "theNonMetaClass", "class"],
 referencedClasses: ["Smalltalk"]
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "receiver",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._valuable())._receiver();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"receiver",{},smalltalk.AnnouncementSubscription)})},
+}, function($ctx1) {$ctx1.fill(self,"receiver",{},globals.AnnouncementSubscription)})},
 args: [],
 source: "receiver\x0a\x09^ self valuable receiver",
 messageSends: ["receiver", "valuable"],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "valuable",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@valuable"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"valuable",{},smalltalk.AnnouncementSubscription)})},
+},
 args: [],
 source: "valuable\x0a\x09^ valuable",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "valuable:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aValuable){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@valuable"]=aValuable;
-return self}, function($ctx1) {$ctx1.fill(self,"valuable:",{aValuable:aValuable},smalltalk.AnnouncementSubscription)})},
+return self},
 args: ["aValuable"],
 source: "valuable: aValuable\x0a\x09valuable := aValuable",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.AnnouncementSubscription);
+globals.AnnouncementSubscription);
 
 
 
-smalltalk.addClass('Announcer', smalltalk.Object, ['registry', 'subscriptions'], 'Kernel-Announcements');
-smalltalk.Announcer.comment="I hold annoncement subscriptions (instances of `AnnouncementSubscription`) in a private registry.\x0aI announce (trigger) announces, which are then dispatched to all subscriptions.\x0a\x0aThe code is based on the announcements as [described by Vassili Bykov](http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?searchCategory=Announcements%20Framework).\x0a\x0a## API\x0a\x0aUse `#announce:` to trigger an announcement.\x0a\x0aUse `#on:do:` or `#on:send:to:` to register subscriptions.\x0a\x0aWhen using `#on:send:to:`, unregistration can be done with `#unregister:`.\x0a\x0a## Usage example:\x0a\x0a    SystemAnnouncer current\x0a        on: ClassAdded\x0a        do: [ :ann | window alert: ann theClass name, ' added' ].";
+smalltalk.addClass('Announcer', globals.Object, ['registry', 'subscriptions'], 'Kernel-Announcements');
+globals.Announcer.comment="I hold annoncement subscriptions (instances of `AnnouncementSubscription`) in a private registry.\x0aI announce (trigger) announces, which are then dispatched to all subscriptions.\x0a\x0aThe code is based on the announcements as [described by Vassili Bykov](http://www.cincomsmalltalk.com/userblogs/vbykov/blogView?searchCategory=Announcements%20Framework).\x0a\x0a## API\x0a\x0aUse `#announce:` to trigger an announcement.\x0a\x0aUse `#on:do:` or `#on:send:to:` to register subscriptions.\x0a\x0aWhen using `#on:send:to:`, unregistration can be done with `#unregister:`.\x0a\x0a## Usage example:\x0a\x0a    SystemAnnouncer current\x0a        on: ClassAdded\x0a        do: [ :ann | window alert: ann theClass name, ' added' ].";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "announce:",
-category: 'announcing',
+protocol: 'announcing',
 fn: function (anAnnouncement){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -187,39 +188,39 @@ _st(self["@subscriptions"])._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(each)._deliver_(anAnnouncement);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"announce:",{anAnnouncement:anAnnouncement},smalltalk.Announcer)})},
+return self}, function($ctx1) {$ctx1.fill(self,"announce:",{anAnnouncement:anAnnouncement},globals.Announcer)})},
 args: ["anAnnouncement"],
 source: "announce: anAnnouncement\x0a\x09subscriptions do: [ :each |\x0a\x09\x09each deliver: anAnnouncement ]",
 messageSends: ["do:", "deliver:"],
 referencedClasses: []
 }),
-smalltalk.Announcer);
+globals.Announcer);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
-function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
+function $OrderedCollection(){return globals.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.Announcer.superclass.fn.prototype._initialize.apply(_st(self), []);
+globals.Announcer.superclass.fn.prototype._initialize.apply(_st(self), []);
 self["@subscriptions"]=_st($OrderedCollection())._new();
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Announcer)})},
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.Announcer)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09subscriptions := OrderedCollection new",
 messageSends: ["initialize", "new"],
 referencedClasses: ["OrderedCollection"]
 }),
-smalltalk.Announcer);
+globals.Announcer);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "on:do:",
-category: 'subscribing',
+protocol: 'subscribing',
 fn: function (aClass,aBlock){
 var self=this;
-function $AnnouncementSubscription(){return smalltalk.AnnouncementSubscription||(typeof AnnouncementSubscription=="undefined"?nil:AnnouncementSubscription)}
+function $AnnouncementSubscription(){return globals.AnnouncementSubscription||(typeof AnnouncementSubscription=="undefined"?nil:AnnouncementSubscription)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 $1=_st($AnnouncementSubscription())._new();
@@ -227,45 +228,79 @@ _st($1)._valuable_(aBlock);
 _st($1)._announcementClass_(aClass);
 $2=_st($1)._yourself();
 _st(self["@subscriptions"])._add_($2);
-return self}, function($ctx1) {$ctx1.fill(self,"on:do:",{aClass:aClass,aBlock:aBlock},smalltalk.Announcer)})},
+return self}, function($ctx1) {$ctx1.fill(self,"on:do:",{aClass:aClass,aBlock:aBlock},globals.Announcer)})},
 args: ["aClass", "aBlock"],
 source: "on: aClass do: aBlock\x0a\x09subscriptions add: (AnnouncementSubscription new\x0a\x09\x09valuable: aBlock;\x0a\x09\x09announcementClass: aClass;\x0a\x09\x09yourself)",
 messageSends: ["add:", "valuable:", "new", "announcementClass:", "yourself"],
 referencedClasses: ["AnnouncementSubscription"]
 }),
-smalltalk.Announcer);
+globals.Announcer);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "on:send:to:",
-category: 'subscribing',
-fn: function (aClass,aSelector,anObject){
+selector: "on:doOnce:",
+protocol: 'subscribing',
+fn: function (aClass,aBlock){
 var self=this;
-function $AnnouncementSubscription(){return smalltalk.AnnouncementSubscription||(typeof AnnouncementSubscription=="undefined"?nil:AnnouncementSubscription)}
-function $MessageSend(){return smalltalk.MessageSend||(typeof MessageSend=="undefined"?nil:MessageSend)}
+var subscription;
+function $AnnouncementSubscription(){return globals.AnnouncementSubscription||(typeof AnnouncementSubscription=="undefined"?nil:AnnouncementSubscription)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
+var $1,$2;
 $1=_st($AnnouncementSubscription())._new();
-$2=_st($MessageSend())._new();
-_st($2)._receiver_(anObject);
-_st($2)._selector_(aSelector);
-$3=_st($2)._yourself();
-_st($1)._valuable_($3);
 _st($1)._announcementClass_(aClass);
-$4=_st($1)._yourself();
-_st(self["@subscriptions"])._add_($4);
-return self}, function($ctx1) {$ctx1.fill(self,"on:send:to:",{aClass:aClass,aSelector:aSelector,anObject:anObject},smalltalk.Announcer)})},
+$2=_st($1)._yourself();
+subscription=$2;
+_st(subscription)._valuable_((function(ann){
+return smalltalk.withContext(function($ctx2) {
+_st(self["@subscriptions"])._remove_(subscription);
+return _st(aBlock)._value_(ann);
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1,1)})}));
+_st(self["@subscriptions"])._add_(subscription);
+return self}, function($ctx1) {$ctx1.fill(self,"on:doOnce:",{aClass:aClass,aBlock:aBlock,subscription:subscription},globals.Announcer)})},
+args: ["aClass", "aBlock"],
+source: "on: aClass doOnce: aBlock\x0a\x09| subscription |\x0a\x09\x0a\x09subscription := AnnouncementSubscription new\x0a\x09\x09announcementClass: aClass;\x0a\x09\x09yourself.\x0a\x09subscription valuable: [ :ann |\x0a\x09\x09subscriptions remove: subscription.\x0a\x09\x09aBlock value: ann ].\x0a\x0a\x09subscriptions add: subscription",
+messageSends: ["announcementClass:", "new", "yourself", "valuable:", "remove:", "value:", "add:"],
+referencedClasses: ["AnnouncementSubscription"]
+}),
+globals.Announcer);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "on:send:to:",
+protocol: 'subscribing',
+fn: function (aClass,aSelector,anObject){
+var self=this;
+function $AnnouncementSubscription(){return globals.AnnouncementSubscription||(typeof AnnouncementSubscription=="undefined"?nil:AnnouncementSubscription)}
+function $MessageSend(){return globals.MessageSend||(typeof MessageSend=="undefined"?nil:MessageSend)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$4,$6,$7,$5,$8,$2;
+$1=self["@subscriptions"];
+$3=_st($AnnouncementSubscription())._new();
+$ctx1.sendIdx["new"]=1;
+$4=$3;
+$6=_st($MessageSend())._new();
+_st($6)._receiver_(anObject);
+_st($6)._selector_(aSelector);
+$7=_st($6)._yourself();
+$ctx1.sendIdx["yourself"]=1;
+$5=$7;
+_st($4)._valuable_($5);
+_st($3)._announcementClass_(aClass);
+$8=_st($3)._yourself();
+$2=$8;
+_st($1)._add_($2);
+return self}, function($ctx1) {$ctx1.fill(self,"on:send:to:",{aClass:aClass,aSelector:aSelector,anObject:anObject},globals.Announcer)})},
 args: ["aClass", "aSelector", "anObject"],
 source: "on: aClass send: aSelector to: anObject\x0a\x09subscriptions add: (AnnouncementSubscription new\x0a\x09\x09valuable: (MessageSend new\x0a\x09\x09\x09receiver: anObject;\x0a\x09\x09\x09selector: aSelector;\x0a\x09\x09\x09yourself);\x0a\x09\x09announcementClass: aClass;\x0a\x09\x09yourself)",
 messageSends: ["add:", "valuable:", "new", "receiver:", "selector:", "yourself", "announcementClass:"],
 referencedClasses: ["AnnouncementSubscription", "MessageSend"]
 }),
-smalltalk.Announcer);
+globals.Announcer);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "unsubscribe:",
-category: 'subscribing',
+protocol: 'subscribing',
 fn: function (anObject){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -273,494 +308,441 @@ self["@subscriptions"]=_st(self["@subscriptions"])._reject_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st(each)._receiver()).__eq(anObject);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"unsubscribe:",{anObject:anObject},smalltalk.Announcer)})},
+return self}, function($ctx1) {$ctx1.fill(self,"unsubscribe:",{anObject:anObject},globals.Announcer)})},
 args: ["anObject"],
 source: "unsubscribe: anObject\x0a\x09subscriptions := subscriptions reject: [ :each |\x0a\x09\x09each receiver = anObject ]",
 messageSends: ["reject:", "=", "receiver"],
 referencedClasses: []
 }),
-smalltalk.Announcer);
+globals.Announcer);
 
 
 
-smalltalk.addClass('SystemAnnouncer', smalltalk.Announcer, [], 'Kernel-Announcements');
-smalltalk.SystemAnnouncer.comment="My unique instance is the global announcer handling all Amber system-related announces.\x0a\x0a## API\x0a\x0aAccess to the unique instance is done via `#current`";
+smalltalk.addClass('SystemAnnouncer', globals.Announcer, [], 'Kernel-Announcements');
+globals.SystemAnnouncer.comment="My unique instance is the global announcer handling all Amber system-related announces.\x0a\x0a## API\x0a\x0aAccess to the unique instance is done via `#current`";
 
-smalltalk.SystemAnnouncer.klass.iVarNames = ['current'];
+globals.SystemAnnouncer.klass.iVarNames = ['current'];
 smalltalk.addMethod(
 smalltalk.method({
 selector: "current",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
 $2=self["@current"];
 if(($receiver = $2) == nil || $receiver == null){
-self["@current"]=smalltalk.SystemAnnouncer.klass.superclass.fn.prototype._new.apply(_st(self), []);
+self["@current"]=globals.SystemAnnouncer.klass.superclass.fn.prototype._new.apply(_st(self), []);
 $1=self["@current"];
 } else {
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"current",{},smalltalk.SystemAnnouncer.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"current",{},globals.SystemAnnouncer.klass)})},
 args: [],
 source: "current\x0a\x09^ current ifNil: [ current := super new ]",
 messageSends: ["ifNil:", "new"],
 referencedClasses: []
 }),
-smalltalk.SystemAnnouncer.klass);
+globals.SystemAnnouncer.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "new",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._shouldNotImplement();
-return self}, function($ctx1) {$ctx1.fill(self,"new",{},smalltalk.SystemAnnouncer.klass)})},
+return self}, function($ctx1) {$ctx1.fill(self,"new",{},globals.SystemAnnouncer.klass)})},
 args: [],
 source: "new\x0a\x09self shouldNotImplement",
 messageSends: ["shouldNotImplement"],
 referencedClasses: []
 }),
-smalltalk.SystemAnnouncer.klass);
+globals.SystemAnnouncer.klass);
 
 
-smalltalk.addClass('SystemAnnouncement', smalltalk.Object, ['theClass'], 'Kernel-Announcements');
-smalltalk.SystemAnnouncement.comment="I am the superclass of all system announcements";
-smalltalk.addMethod(
-smalltalk.method({
-selector: "theClass",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=self["@theClass"];
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"theClass",{},smalltalk.SystemAnnouncement)})},
-args: [],
-source: "theClass\x0a\x09^ theClass",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.SystemAnnouncement);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "theClass:",
-category: 'accessing',
-fn: function (aClass){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self["@theClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass},smalltalk.SystemAnnouncement)})},
-args: ["aClass"],
-source: "theClass: aClass\x0a\x09theClass := aClass",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.SystemAnnouncement);
-
+smalltalk.addClass('SystemAnnouncement', globals.Object, [], 'Kernel-Announcements');
+globals.SystemAnnouncement.comment="I am the superclass of all system announcements";
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "heliosClass",
-category: 'helios',
+protocol: 'helios',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "announcement";
-}, function($ctx1) {$ctx1.fill(self,"heliosClass",{},smalltalk.SystemAnnouncement.klass)})},
+},
 args: [],
 source: "heliosClass\x0a\x09^ 'announcement'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.SystemAnnouncement.klass);
+globals.SystemAnnouncement.klass);
 
 
-smalltalk.addClass('ClassAnnouncement', smalltalk.SystemAnnouncement, ['theClass'], 'Kernel-Announcements');
-smalltalk.ClassAnnouncement.comment="I am the abstract superclass of class-related announcements.";
+smalltalk.addClass('ClassAnnouncement', globals.SystemAnnouncement, ['theClass'], 'Kernel-Announcements');
+globals.ClassAnnouncement.comment="I am the abstract superclass of class-related announcements.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "theClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@theClass"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"theClass",{},smalltalk.ClassAnnouncement)})},
+},
 args: [],
 source: "theClass\x0a\x09^ theClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ClassAnnouncement);
+globals.ClassAnnouncement);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "theClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@theClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass},smalltalk.ClassAnnouncement)})},
+return self},
 args: ["aClass"],
 source: "theClass: aClass\x0a\x09theClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ClassAnnouncement);
+globals.ClassAnnouncement);
 
 
 
-smalltalk.addClass('ClassAdded', smalltalk.ClassAnnouncement, [], 'Kernel-Announcements');
-smalltalk.ClassAdded.comment="I am emitted when a class is added to the system.\x0aSee ClassBuilder >> #addSubclassOf:... methods";
+smalltalk.addClass('ClassAdded', globals.ClassAnnouncement, [], 'Kernel-Announcements');
+globals.ClassAdded.comment="I am emitted when a class is added to the system.\x0aSee ClassBuilder >> #addSubclassOf:... methods";
 
 
-smalltalk.addClass('ClassCommentChanged', smalltalk.ClassAnnouncement, [], 'Kernel-Announcements');
-smalltalk.ClassCommentChanged.comment="I am emitted when the comment of a class changes. (Behavior >> #comment)";
+smalltalk.addClass('ClassCommentChanged', globals.ClassAnnouncement, [], 'Kernel-Announcements');
+globals.ClassCommentChanged.comment="I am emitted when the comment of a class changes. (Behavior >> #comment)";
 
 
-smalltalk.addClass('ClassDefinitionChanged', smalltalk.ClassAnnouncement, [], 'Kernel-Announcements');
-smalltalk.ClassDefinitionChanged.comment="I am emitted when the definition of a class changes.\x0aSee ClassBuilder >> #class:instanceVariableNames:";
+smalltalk.addClass('ClassDefinitionChanged', globals.ClassAnnouncement, [], 'Kernel-Announcements');
+globals.ClassDefinitionChanged.comment="I am emitted when the definition of a class changes.\x0aSee ClassBuilder >> #class:instanceVariableNames:";
 
 
-smalltalk.addClass('ClassMigrated', smalltalk.ClassAnnouncement, ['oldClass'], 'Kernel-Announcements');
-smalltalk.ClassMigrated.comment="I am emitted when a class is migrated.";
+smalltalk.addClass('ClassMigrated', globals.ClassAnnouncement, ['oldClass'], 'Kernel-Announcements');
+globals.ClassMigrated.comment="I am emitted when a class is migrated.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@oldClass"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"oldClass",{},smalltalk.ClassMigrated)})},
+},
 args: [],
 source: "oldClass\x0a\x09^ oldClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ClassMigrated);
+globals.ClassMigrated);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@oldClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"oldClass:",{aClass:aClass},smalltalk.ClassMigrated)})},
+return self},
 args: ["aClass"],
 source: "oldClass: aClass\x0a\x09oldClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ClassMigrated);
+globals.ClassMigrated);
 
 
 
-smalltalk.addClass('ClassMoved', smalltalk.ClassAnnouncement, ['oldPackage'], 'Kernel-Announcements');
-smalltalk.ClassMoved.comment="I am emitted when a class is moved from one package to another.";
+smalltalk.addClass('ClassMoved', globals.ClassAnnouncement, ['oldPackage'], 'Kernel-Announcements');
+globals.ClassMoved.comment="I am emitted when a class is moved from one package to another.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldPackage",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@oldPackage"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"oldPackage",{},smalltalk.ClassMoved)})},
+},
 args: [],
 source: "oldPackage\x0a\x09^ oldPackage",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ClassMoved);
+globals.ClassMoved);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldPackage:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aPackage){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@oldPackage"]=aPackage;
-return self}, function($ctx1) {$ctx1.fill(self,"oldPackage:",{aPackage:aPackage},smalltalk.ClassMoved)})},
+return self},
 args: ["aPackage"],
 source: "oldPackage: aPackage\x0a\x09oldPackage := aPackage",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ClassMoved);
+globals.ClassMoved);
 
 
 
-smalltalk.addClass('ClassRemoved', smalltalk.ClassAnnouncement, [], 'Kernel-Announcements');
-smalltalk.ClassRemoved.comment="I am emitted when a class is removed.\x0aSee Smalltalk >> #removeClass:";
+smalltalk.addClass('ClassRemoved', globals.ClassAnnouncement, [], 'Kernel-Announcements');
+globals.ClassRemoved.comment="I am emitted when a class is removed.\x0aSee Smalltalk >> #removeClass:";
 
 
-smalltalk.addClass('ClassRenamed', smalltalk.ClassAnnouncement, [], 'Kernel-Announcements');
-smalltalk.ClassRenamed.comment="I am emitted when a class is renamed.\x0aSee ClassBuilder >> #renameClass:to:";
+smalltalk.addClass('ClassRenamed', globals.ClassAnnouncement, [], 'Kernel-Announcements');
+globals.ClassRenamed.comment="I am emitted when a class is renamed.\x0aSee ClassBuilder >> #renameClass:to:";
 
 
-smalltalk.addClass('MethodAnnouncement', smalltalk.SystemAnnouncement, ['method'], 'Kernel-Announcements');
-smalltalk.MethodAnnouncement.comment="I am the abstract superclass of method-related announcements.";
+smalltalk.addClass('MethodAnnouncement', globals.SystemAnnouncement, ['method'], 'Kernel-Announcements');
+globals.MethodAnnouncement.comment="I am the abstract superclass of method-related announcements.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "method",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@method"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"method",{},smalltalk.MethodAnnouncement)})},
+},
 args: [],
 source: "method\x0a\x09^ method",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MethodAnnouncement);
+globals.MethodAnnouncement);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "method:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aCompiledMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@method"]=aCompiledMethod;
-return self}, function($ctx1) {$ctx1.fill(self,"method:",{aCompiledMethod:aCompiledMethod},smalltalk.MethodAnnouncement)})},
+return self},
 args: ["aCompiledMethod"],
 source: "method: aCompiledMethod\x0a\x09method := aCompiledMethod",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MethodAnnouncement);
+globals.MethodAnnouncement);
 
 
 
-smalltalk.addClass('MethodAdded', smalltalk.MethodAnnouncement, [], 'Kernel-Announcements');
-smalltalk.MethodAdded.comment="I am emitted when a `CompiledMethod` is added to a class.";
+smalltalk.addClass('MethodAdded', globals.MethodAnnouncement, [], 'Kernel-Announcements');
+globals.MethodAdded.comment="I am emitted when a `CompiledMethod` is added to a class.";
 
 
-smalltalk.addClass('MethodModified', smalltalk.MethodAnnouncement, ['oldMethod'], 'Kernel-Announcements');
-smalltalk.MethodModified.comment="I am emitted when a `CompiledMethod` is modified (a new method is installed). I hold a reference to the old method being replaced.";
+smalltalk.addClass('MethodModified', globals.MethodAnnouncement, ['oldMethod'], 'Kernel-Announcements');
+globals.MethodModified.comment="I am emitted when a `CompiledMethod` is modified (a new method is installed). I hold a reference to the old method being replaced.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldMethod",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@oldMethod"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"oldMethod",{},smalltalk.MethodModified)})},
+},
 args: [],
 source: "oldMethod\x0a\x09^ oldMethod",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MethodModified);
+globals.MethodModified);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldMethod:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@oldMethod"]=aMethod;
-return self}, function($ctx1) {$ctx1.fill(self,"oldMethod:",{aMethod:aMethod},smalltalk.MethodModified)})},
+return self},
 args: ["aMethod"],
 source: "oldMethod: aMethod\x0a\x09oldMethod := aMethod",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MethodModified);
+globals.MethodModified);
 
 
 
-smalltalk.addClass('MethodMoved', smalltalk.MethodAnnouncement, ['oldProtocol'], 'Kernel-Announcements');
-smalltalk.MethodMoved.comment="I am emitted when a `CompiledMethod` is moved to another protocol. I hold a refernce to the old protocol of the method.";
+smalltalk.addClass('MethodMoved', globals.MethodAnnouncement, ['oldProtocol'], 'Kernel-Announcements');
+globals.MethodMoved.comment="I am emitted when a `CompiledMethod` is moved to another protocol. I hold a refernce to the old protocol of the method.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldProtocol",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@oldProtocol"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"oldProtocol",{},smalltalk.MethodMoved)})},
+},
 args: [],
 source: "oldProtocol\x0a\x09^ oldProtocol",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MethodMoved);
+globals.MethodMoved);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "oldProtocol:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@oldProtocol"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"oldProtocol:",{aString:aString},smalltalk.MethodMoved)})},
+return self},
 args: ["aString"],
 source: "oldProtocol: aString\x0a\x09oldProtocol := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MethodMoved);
+globals.MethodMoved);
 
 
 
-smalltalk.addClass('MethodRemoved', smalltalk.MethodAnnouncement, [], 'Kernel-Announcements');
-smalltalk.MethodRemoved.comment="I am emitted when a `CompiledMethod` is removed from a class.";
+smalltalk.addClass('MethodRemoved', globals.MethodAnnouncement, [], 'Kernel-Announcements');
+globals.MethodRemoved.comment="I am emitted when a `CompiledMethod` is removed from a class.";
 
 
-smalltalk.addClass('PackageAnnouncement', smalltalk.SystemAnnouncement, ['package'], 'Kernel-Announcements');
-smalltalk.PackageAnnouncement.comment="I am the abstract superclass of package-related announcements.";
+smalltalk.addClass('PackageAnnouncement', globals.SystemAnnouncement, ['package'], 'Kernel-Announcements');
+globals.PackageAnnouncement.comment="I am the abstract superclass of package-related announcements.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "package",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@package"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"package",{},smalltalk.PackageAnnouncement)})},
+},
 args: [],
 source: "package\x0a\x09^ package",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.PackageAnnouncement);
+globals.PackageAnnouncement);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "package:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aPackage){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@package"]=aPackage;
-return self}, function($ctx1) {$ctx1.fill(self,"package:",{aPackage:aPackage},smalltalk.PackageAnnouncement)})},
+return self},
 args: ["aPackage"],
 source: "package: aPackage\x0a\x09package := aPackage",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.PackageAnnouncement);
+globals.PackageAnnouncement);
 
 
 
-smalltalk.addClass('PackageAdded', smalltalk.PackageAnnouncement, [], 'Kernel-Announcements');
-smalltalk.PackageAdded.comment="I am emitted when a `Package` is added to the system.";
+smalltalk.addClass('PackageAdded', globals.PackageAnnouncement, [], 'Kernel-Announcements');
+globals.PackageAdded.comment="I am emitted when a `Package` is added to the system.";
 
 
-smalltalk.addClass('PackageRemoved', smalltalk.PackageAnnouncement, [], 'Kernel-Announcements');
-smalltalk.PackageRemoved.comment="I am emitted when a `Package` is removed from the system.";
+smalltalk.addClass('PackageRemoved', globals.PackageAnnouncement, [], 'Kernel-Announcements');
+globals.PackageRemoved.comment="I am emitted when a `Package` is removed from the system.";
 
 
-smalltalk.addClass('ProtocolAnnouncement', smalltalk.SystemAnnouncement, ['theClass', 'protocol'], 'Kernel-Announcements');
-smalltalk.ProtocolAnnouncement.comment="I am the abstract superclass of protocol-related announcements.";
+smalltalk.addClass('ProtocolAnnouncement', globals.SystemAnnouncement, ['theClass', 'protocol'], 'Kernel-Announcements');
+globals.ProtocolAnnouncement.comment="I am the abstract superclass of protocol-related announcements.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "protocol",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@protocol"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"protocol",{},smalltalk.ProtocolAnnouncement)})},
+},
 args: [],
 source: "protocol\x0a\x09^ protocol",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ProtocolAnnouncement);
+globals.ProtocolAnnouncement);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "protocol:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@protocol"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"protocol:",{aString:aString},smalltalk.ProtocolAnnouncement)})},
+return self},
 args: ["aString"],
 source: "protocol: aString\x0a\x09protocol := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ProtocolAnnouncement);
+globals.ProtocolAnnouncement);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "theClass",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@theClass"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"theClass",{},smalltalk.ProtocolAnnouncement)})},
+},
 args: [],
 source: "theClass\x0a\x09^ theClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ProtocolAnnouncement);
+globals.ProtocolAnnouncement);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "theClass:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aClass){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@theClass"]=aClass;
-return self}, function($ctx1) {$ctx1.fill(self,"theClass:",{aClass:aClass},smalltalk.ProtocolAnnouncement)})},
+return self},
 args: ["aClass"],
 source: "theClass: aClass\x0a\x09theClass := aClass",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ProtocolAnnouncement);
+globals.ProtocolAnnouncement);
 
 
 
-smalltalk.addClass('ProtocolAdded', smalltalk.ProtocolAnnouncement, [], 'Kernel-Announcements');
-smalltalk.ProtocolAdded.comment="I am emitted when a protocol is added to a class.";
+smalltalk.addClass('ProtocolAdded', globals.ProtocolAnnouncement, [], 'Kernel-Announcements');
+globals.ProtocolAdded.comment="I am emitted when a protocol is added to a class.";
 
 
-smalltalk.addClass('ProtocolRemoved', smalltalk.ProtocolAnnouncement, [], 'Kernel-Announcements');
-smalltalk.ProtocolRemoved.comment="I am emitted when a protocol is removed from a class.";
+smalltalk.addClass('ProtocolRemoved', globals.ProtocolAnnouncement, [], 'Kernel-Announcements');
+globals.ProtocolRemoved.comment="I am emitted when a protocol is removed from a class.";
 
 });

File diff suppressed because it is too large
+ 287 - 176
js/Kernel-Classes.js


File diff suppressed because it is too large
+ 428 - 162
js/Kernel-Collections.js


+ 91 - 284
js/Kernel-Exceptions.js

@@ -1,283 +1,278 @@
-define("amber_core/Kernel-Exceptions", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Kernel-Exceptions", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Kernel-Exceptions');
 smalltalk.packages["Kernel-Exceptions"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('Error', smalltalk.Object, ['messageText'], 'Kernel-Exceptions');
-smalltalk.Error.comment="From the ANSI standard:\x0a\x0aThis protocol describes the behavior of instances of class `Error`.\x0aThese are used to represent error conditions that prevent the normal continuation of processing.\x0aActual error exceptions used by an application may be subclasses of this class.\x0aAs `Error` is explicitly specified to be subclassable, conforming implementations must implement its behavior in a non-fragile manner.";
+smalltalk.addClass('Error', globals.Object, ['messageText'], 'Kernel-Exceptions');
+globals.Error.comment="From the ANSI standard:\x0a\x0aThis protocol describes the behavior of instances of class `Error`.\x0aThese are used to represent error conditions that prevent the normal continuation of processing.\x0aActual error exceptions used by an application may be subclasses of this class.\x0aAs `Error` is explicitly specified to be subclassable, conforming implementations must implement its behavior in a non-fragile manner.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 return self.context;
-return self}, function($ctx1) {$ctx1.fill(self,"context",{},smalltalk.Error)})},
+return self}, function($ctx1) {$ctx1.fill(self,"context",{},globals.Error)})},
 args: [],
 source: "context\x0a\x09<return self.context>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._messageText_("Errorclass: ".__comma(_st(self._class())._name()));
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.Error)})},
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.Error)})},
 args: [],
 source: "initialize\x0a\x09self messageText: 'Errorclass: ', (self class name).",
 messageSends: ["messageText:", ",", "name", "class"],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isSmalltalkError",
-category: 'testing',
+protocol: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 return self.smalltalkError === true;
-return self}, function($ctx1) {$ctx1.fill(self,"isSmalltalkError",{},smalltalk.Error)})},
+return self}, function($ctx1) {$ctx1.fill(self,"isSmalltalkError",{},globals.Error)})},
 args: [],
 source: "isSmalltalkError\x0a\x09<return self.smalltalkError === true>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "jsStack",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 return self.stack;
-return self}, function($ctx1) {$ctx1.fill(self,"jsStack",{},smalltalk.Error)})},
+return self}, function($ctx1) {$ctx1.fill(self,"jsStack",{},globals.Error)})},
 args: [],
 source: "jsStack\x0a\x09<return self.stack>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@messageText"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"messageText",{},smalltalk.Error)})},
+},
 args: [],
-source: "messageText\x0a\x09^messageText",
+source: "messageText\x0a\x09^ messageText",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aString){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@messageText"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"messageText:",{aString:aString},smalltalk.Error)})},
+return self},
 args: ["aString"],
 source: "messageText: aString\x0a\x09messageText := aString",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "resignal",
-category: 'signaling',
+protocol: 'signaling',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 throw(self);
-return self}, function($ctx1) {$ctx1.fill(self,"resignal",{},smalltalk.Error)})},
+return self}, function($ctx1) {$ctx1.fill(self,"resignal",{},globals.Error)})},
 args: [],
 source: "resignal\x0a\x09\x22Resignal the receiver without changing its exception context\x22\x0a\x09\x0a\x09<throw(self)>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "signal",
-category: 'signaling',
+protocol: 'signaling',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self);
-return self}, function($ctx1) {$ctx1.fill(self,"signal",{},smalltalk.Error)})},
+return self}, function($ctx1) {$ctx1.fill(self,"signal",{},globals.Error)})},
 args: [],
 source: "signal\x0a\x09<self.context = smalltalk.getThisContext(); self.smalltalkError = true; throw(self)>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "signal:",
-category: 'signaling',
+protocol: 'signaling',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._messageText_(aString);
 self._signal();
-return self}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString},smalltalk.Error)})},
+return self}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString},globals.Error)})},
 args: ["aString"],
 source: "signal: aString\x0a\x09self messageText: aString.\x0a\x09self signal",
 messageSends: ["messageText:", "signal"],
 referencedClasses: []
 }),
-smalltalk.Error);
+globals.Error);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "heliosClass",
-category: 'helios',
+protocol: 'helios',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "exception";
-}, function($ctx1) {$ctx1.fill(self,"heliosClass",{},smalltalk.Error.klass)})},
+},
 args: [],
 source: "heliosClass\x0a\x09^ 'exception'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.Error.klass);
+globals.Error.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "signal",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._new())._signal();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"signal",{},smalltalk.Error.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"signal",{},globals.Error.klass)})},
 args: [],
-source: "signal\x0a\x09^self new signal",
+source: "signal\x0a\x09^ self new signal",
 messageSends: ["signal", "new"],
 referencedClasses: []
 }),
-smalltalk.Error.klass);
+globals.Error.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "signal:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._new())._signal_(aString);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString},smalltalk.Error.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"signal:",{aString:aString},globals.Error.klass)})},
 args: ["aString"],
-source: "signal: aString\x0a\x09\x09^self new\x0a\x09\x09signal: aString",
+source: "signal: aString\x0a\x09^ self new\x0a\x09\x09signal: aString",
 messageSends: ["signal:", "new"],
 referencedClasses: []
 }),
-smalltalk.Error.klass);
+globals.Error.klass);
 
 
-smalltalk.addClass('JavaScriptException', smalltalk.Error, ['exception'], 'Kernel-Exceptions');
-smalltalk.JavaScriptException.comment="A JavaScriptException is thrown when a non-Smalltalk exception occurs while in the Smalltalk stack.\x0aSee `boot.js` `inContext()` and `BlockClosure >> on:do:`";
+smalltalk.addClass('JavaScriptException', globals.Error, ['exception'], 'Kernel-Exceptions');
+globals.JavaScriptException.comment="A JavaScriptException is thrown when a non-Smalltalk exception occurs while in the Smalltalk stack.\x0aSee `boot.js` `inContext()` and `BlockClosure >> on:do:`";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "context:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aMethodContext){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self.context = aMethodContext;
-return self}, function($ctx1) {$ctx1.fill(self,"context:",{aMethodContext:aMethodContext},smalltalk.JavaScriptException)})},
+return self}, function($ctx1) {$ctx1.fill(self,"context:",{aMethodContext:aMethodContext},globals.JavaScriptException)})},
 args: ["aMethodContext"],
 source: "context: aMethodContext\x0a\x09\x22Set the context from the outside.\x0a\x09See boot.js `inContext()` exception handling\x22\x0a\x09\x0a\x09<self.context = aMethodContext>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.JavaScriptException);
+globals.JavaScriptException);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "exception",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@exception"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"exception",{},smalltalk.JavaScriptException)})},
+},
 args: [],
 source: "exception\x0a\x09^ exception",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.JavaScriptException);
+globals.JavaScriptException);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "exception:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (anException){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@exception"]=anException;
-return self}, function($ctx1) {$ctx1.fill(self,"exception:",{anException:anException},smalltalk.JavaScriptException)})},
+return self},
 args: ["anException"],
 source: "exception: anException\x0a\x09exception := anException",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.JavaScriptException);
+globals.JavaScriptException);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 return 'JavaScript exception: ' + self["@exception"].toString();
-return self}, function($ctx1) {$ctx1.fill(self,"messageText",{},smalltalk.JavaScriptException)})},
+return self}, function($ctx1) {$ctx1.fill(self,"messageText",{},globals.JavaScriptException)})},
 args: [],
 source: "messageText\x0a\x09<return 'JavaScript exception: ' + self[\x22@exception\x22].toString()>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.JavaScriptException);
+globals.JavaScriptException);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "on:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (anException){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -287,18 +282,18 @@ _st($2)._exception_(anException);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{anException:anException},smalltalk.JavaScriptException.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:",{anException:anException},globals.JavaScriptException.klass)})},
 args: ["anException"],
 source: "on: anException\x0a\x09^ self new\x0a\x09\x09exception: anException;\x0a\x09\x09yourself",
 messageSends: ["exception:", "new", "yourself"],
 referencedClasses: []
 }),
-smalltalk.JavaScriptException.klass);
+globals.JavaScriptException.klass);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "on:context:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (anException,aMethodContext){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -309,323 +304,135 @@ _st($2)._context_(aMethodContext);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:context:",{anException:anException,aMethodContext:aMethodContext},smalltalk.JavaScriptException.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:context:",{anException:anException,aMethodContext:aMethodContext},globals.JavaScriptException.klass)})},
 args: ["anException", "aMethodContext"],
 source: "on: anException context: aMethodContext\x0a\x09^ self new\x0a\x09\x09exception: anException;\x0a\x09\x09context: aMethodContext;\x0a\x09\x09yourself",
 messageSends: ["exception:", "new", "context:", "yourself"],
 referencedClasses: []
 }),
-smalltalk.JavaScriptException.klass);
+globals.JavaScriptException.klass);
 
 
-smalltalk.addClass('MessageNotUnderstood', smalltalk.Error, ['message', 'receiver'], 'Kernel-Exceptions');
-smalltalk.MessageNotUnderstood.comment="This exception is provided to support `Object>>doesNotUnderstand:`.";
+smalltalk.addClass('MessageNotUnderstood', globals.Error, ['message', 'receiver'], 'Kernel-Exceptions');
+globals.MessageNotUnderstood.comment="This exception is provided to support `Object>>doesNotUnderstand:`.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "message",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@message"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"message",{},smalltalk.MessageNotUnderstood)})},
+},
 args: [],
-source: "message\x0a\x09^message",
+source: "message\x0a\x09^ message",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MessageNotUnderstood);
+globals.MessageNotUnderstood);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "message:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (aMessage){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@message"]=aMessage;
-return self}, function($ctx1) {$ctx1.fill(self,"message:",{aMessage:aMessage},smalltalk.MessageNotUnderstood)})},
+return self},
 args: ["aMessage"],
 source: "message: aMessage\x0a\x09message := aMessage",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MessageNotUnderstood);
+globals.MessageNotUnderstood);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(_st(self._receiver())._asString()).__comma(" does not understand #")).__comma(_st(self._message())._selector());
+$ctx1.sendIdx[","]=1;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"messageText",{},smalltalk.MessageNotUnderstood)})},
+}, function($ctx1) {$ctx1.fill(self,"messageText",{},globals.MessageNotUnderstood)})},
 args: [],
-source: "messageText\x0a\x09^self receiver asString, ' does not understand #', self message selector",
+source: "messageText\x0a\x09^ self receiver asString, ' does not understand #', self message selector",
 messageSends: [",", "asString", "receiver", "selector", "message"],
 referencedClasses: []
 }),
-smalltalk.MessageNotUnderstood);
+globals.MessageNotUnderstood);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "receiver",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@receiver"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"receiver",{},smalltalk.MessageNotUnderstood)})},
+},
 args: [],
-source: "receiver\x0a\x09^receiver",
+source: "receiver\x0a\x09^ receiver",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MessageNotUnderstood);
+globals.MessageNotUnderstood);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "receiver:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (anObject){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@receiver"]=anObject;
-return self}, function($ctx1) {$ctx1.fill(self,"receiver:",{anObject:anObject},smalltalk.MessageNotUnderstood)})},
+return self},
 args: ["anObject"],
 source: "receiver: anObject\x0a\x09receiver := anObject",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.MessageNotUnderstood);
+globals.MessageNotUnderstood);
 
 
 
-smalltalk.addClass('NonBooleanReceiver', smalltalk.Error, ['object'], 'Kernel-Exceptions');
-smalltalk.NonBooleanReceiver.comment="NonBooleanReceiver exceptions may be thrown when executing inlined methods such as `#ifTrue:` with a non boolean receiver.";
+smalltalk.addClass('NonBooleanReceiver', globals.Error, ['object'], 'Kernel-Exceptions');
+globals.NonBooleanReceiver.comment="NonBooleanReceiver exceptions may be thrown when executing inlined methods such as `#ifTrue:` with a non boolean receiver.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "object",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@object"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"object",{},smalltalk.NonBooleanReceiver)})},
+},
 args: [],
 source: "object\x0a\x09^ object",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.NonBooleanReceiver);
+globals.NonBooleanReceiver);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "object:",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (anObject){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@object"]=anObject;
-return self}, function($ctx1) {$ctx1.fill(self,"object:",{anObject:anObject},smalltalk.NonBooleanReceiver)})},
+return self},
 args: ["anObject"],
 source: "object: anObject\x0a\x09object := anObject",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.NonBooleanReceiver);
-
-
-
-smalltalk.addClass('ErrorHandler', smalltalk.Object, [], 'Kernel-Exceptions');
-smalltalk.ErrorHandler.comment="I am used to manage Smalltalk errors.\x0aSee `boot.js` `handleError()` function.\x0a\x0aSubclasses can register themselves as the current handler with\x0a`ErrorHandler class >> register`.\x0a\x0aSubclasses may override `#handleError:` to perform an action on the thrown exception.\x0aThe default behavior is to log the error and the context stack to the JavaScript console.";
-smalltalk.addMethod(
-smalltalk.method({
-selector: "handleError:",
-category: 'error handling',
-fn: function (anError){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(anError)._context();
-if(($receiver = $1) == nil || $receiver == null){
-$1;
-} else {
-self._logErrorContext_(_st(anError)._context());
-};
-self._logError_(anError);
-return self}, function($ctx1) {$ctx1.fill(self,"handleError:",{anError:anError},smalltalk.ErrorHandler)})},
-args: ["anError"],
-source: "handleError: anError\x0a\x09anError context ifNotNil: [self logErrorContext: anError context].\x0a\x09self logError: anError",
-messageSends: ["ifNotNil:", "context", "logErrorContext:", "logError:"],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "log:",
-category: 'private',
-fn: function (aString){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-_st(console)._log_(aString);
-return self}, function($ctx1) {$ctx1.fill(self,"log:",{aString:aString},smalltalk.ErrorHandler)})},
-args: ["aString"],
-source: "log: aString\x0a\x09console log: aString",
-messageSends: ["log:"],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "logContext:",
-category: 'private',
-fn: function (aContext){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(aContext)._home();
-if(($receiver = $1) == nil || $receiver == null){
-$1;
-} else {
-self._logContext_(_st(aContext)._home());
-};
-self._log_(_st(aContext)._asString());
-return self}, function($ctx1) {$ctx1.fill(self,"logContext:",{aContext:aContext},smalltalk.ErrorHandler)})},
-args: ["aContext"],
-source: "logContext: aContext\x0a\x09aContext home ifNotNil: [\x0a\x09\x09self logContext: aContext home].\x0a\x09self log: aContext asString",
-messageSends: ["ifNotNil:", "home", "logContext:", "log:", "asString"],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "logError:",
-category: 'private',
-fn: function (anError){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self._log_(_st(anError)._messageText());
-return self}, function($ctx1) {$ctx1.fill(self,"logError:",{anError:anError},smalltalk.ErrorHandler)})},
-args: ["anError"],
-source: "logError: anError\x0a\x09self log: anError messageText",
-messageSends: ["log:", "messageText"],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "logErrorContext:",
-category: 'private',
-fn: function (aContext){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
-$1=aContext;
-if(($receiver = $1) == nil || $receiver == null){
-$1;
-} else {
-$2=_st(aContext)._home();
-if(($receiver = $2) == nil || $receiver == null){
-$2;
-} else {
-self._logContext_(_st(aContext)._home());
-};
-};
-return self}, function($ctx1) {$ctx1.fill(self,"logErrorContext:",{aContext:aContext},smalltalk.ErrorHandler)})},
-args: ["aContext"],
-source: "logErrorContext: aContext\x0a\x09aContext ifNotNil: [\x0a\x09\x09aContext home ifNotNil: [\x0a\x09\x09\x09self logContext: aContext home]]",
-messageSends: ["ifNotNil:", "home", "logContext:"],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler);
-
-
-smalltalk.ErrorHandler.klass.iVarNames = ['current'];
-smalltalk.addMethod(
-smalltalk.method({
-selector: "current",
-category: 'accessing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=self["@current"];
-if(($receiver = $2) == nil || $receiver == null){
-self["@current"]=self._new();
-$1=self["@current"];
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"current",{},smalltalk.ErrorHandler.klass)})},
-args: [],
-source: "current\x0a\x09^current ifNil: [current := self new]",
-messageSends: ["ifNil:", "new"],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "initialize",
-category: 'initialization',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self._register();
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ErrorHandler.klass)})},
-args: [],
-source: "initialize\x0a\x09self register",
-messageSends: ["register"],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "register",
-category: 'initialization',
-fn: function (){
-var self=this;
-function $ErrorHandler(){return smalltalk.ErrorHandler||(typeof ErrorHandler=="undefined"?nil:ErrorHandler)}
-return smalltalk.withContext(function($ctx1) { 
-_st($ErrorHandler())._setCurrent_(self._new());
-return self}, function($ctx1) {$ctx1.fill(self,"register",{},smalltalk.ErrorHandler.klass)})},
-args: [],
-source: "register\x0a\x09ErrorHandler setCurrent: self new",
-messageSends: ["setCurrent:", "new"],
-referencedClasses: ["ErrorHandler"]
-}),
-smalltalk.ErrorHandler.klass);
+globals.NonBooleanReceiver);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "setCurrent:",
-category: 'accessing',
-fn: function (anHandler){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self["@current"]=anHandler;
-return self}, function($ctx1) {$ctx1.fill(self,"setCurrent:",{anHandler:anHandler},smalltalk.ErrorHandler.klass)})},
-args: ["anHandler"],
-source: "setCurrent: anHandler\x0a\x09current := anHandler",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.ErrorHandler.klass);
 
 });

File diff suppressed because it is too large
+ 584 - 417
js/Kernel-ImportExport.js


File diff suppressed because it is too large
+ 444 - 278
js/Kernel-Infrastructure.js


File diff suppressed because it is too large
+ 231 - 223
js/Kernel-Methods.js


File diff suppressed because it is too large
+ 466 - 274
js/Kernel-Objects.js


File diff suppressed because it is too large
+ 547 - 295
js/Kernel-Tests.js


+ 22 - 161
js/Kernel-Transcript.js

@@ -1,222 +1,83 @@
-define("amber_core/Kernel-Transcript", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st){
+define("amber_core/Kernel-Transcript", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Kernel-Transcript');
 smalltalk.packages["Kernel-Transcript"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('ConsoleTranscript', smalltalk.Object, ['textarea'], 'Kernel-Transcript');
-smalltalk.ConsoleTranscript.comment="I am a specific transcript emitting to the JavaScript console.\x0a\x0aIf no other transcript is registered, I am the default.";
+smalltalk.addClass('ConsoleTranscript', globals.Object, ['textarea'], 'Kernel-Transcript');
+globals.ConsoleTranscript.comment="I am a specific transcript emitting to the JavaScript console.\x0a\x0aIf no other transcript is registered, I am the default.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "clear",
-category: 'printing',
+protocol: 'printing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self}, function($ctx1) {$ctx1.fill(self,"clear",{},smalltalk.ConsoleTranscript)})},
+return self},
 args: [],
 source: "clear\x0a\x09\x22no op\x22",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ConsoleTranscript);
+globals.ConsoleTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "cr",
-category: 'printing',
+protocol: 'printing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self}, function($ctx1) {$ctx1.fill(self,"cr",{},smalltalk.ConsoleTranscript)})},
+return self},
 args: [],
 source: "cr\x0a\x09\x22no op\x22",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ConsoleTranscript);
+globals.ConsoleTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "open",
-category: 'actions',
+protocol: 'actions',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
-return self}, function($ctx1) {$ctx1.fill(self,"open",{},smalltalk.ConsoleTranscript)})},
+return self},
 args: [],
 source: "open",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ConsoleTranscript);
+globals.ConsoleTranscript);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "show:",
-category: 'printing',
+protocol: 'printing',
 fn: function (anObject){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 console.log(String(_st(anObject)._asString()));
-return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject},smalltalk.ConsoleTranscript)})},
+return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject},globals.ConsoleTranscript)})},
 args: ["anObject"],
 source: "show: anObject\x0a\x22Smalltalk objects should have no trouble displaying themselves on the Transcript; Javascript objects don't know how, so must be wrapped in a JSObectProxy.\x22\x0a<console.log(String(_st(anObject)._asString()))>",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ConsoleTranscript);
+globals.ConsoleTranscript);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
-function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+function $Transcript(){return globals.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
 return smalltalk.withContext(function($ctx1) { 
-_st($Transcript())._register_(self._new());
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ConsoleTranscript.klass)})},
+_st($Transcript())._registerIfNone_(self._new());
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.ConsoleTranscript.klass)})},
 args: [],
-source: "initialize\x0a\x09Transcript register: self new",
-messageSends: ["register:", "new"],
+source: "initialize\x0a\x09Transcript registerIfNone: self new",
+messageSends: ["registerIfNone:", "new"],
 referencedClasses: ["Transcript"]
 }),
-smalltalk.ConsoleTranscript.klass);
-
-
-smalltalk.addClass('Transcript', smalltalk.Object, [], 'Kernel-Transcript');
-smalltalk.Transcript.comment="I am a facade for Transcript actions.\x0a\x0aI delegate actions to the currently registered transcript.\x0a\x0a## API\x0a\x0a    Transcript \x0a        show: 'hello world';\x0a        cr;\x0a        show: anObject.";
-
-smalltalk.Transcript.klass.iVarNames = ['current'];
-smalltalk.addMethod(
-smalltalk.method({
-selector: "clear",
-category: 'printing',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-_st(self._current())._clear();
-return self}, function($ctx1) {$ctx1.fill(self,"clear",{},smalltalk.Transcript.klass)})},
-args: [],
-source: "clear\x0a\x09self current clear",
-messageSends: ["clear", "current"],
-referencedClasses: []
-}),
-smalltalk.Transcript.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "cr",
-category: 'printing',
-fn: function (){
-var self=this;
-function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
-return smalltalk.withContext(function($ctx1) { 
-_st(self._current())._show_(_st($String())._cr());
-return self}, function($ctx1) {$ctx1.fill(self,"cr",{},smalltalk.Transcript.klass)})},
-args: [],
-source: "cr\x0a\x09self current show: String cr",
-messageSends: ["show:", "current", "cr"],
-referencedClasses: ["String"]
-}),
-smalltalk.Transcript.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "current",
-category: 'instance creation',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=self["@current"];
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"current",{},smalltalk.Transcript.klass)})},
-args: [],
-source: "current\x0a\x09^current",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Transcript.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "inspect:",
-category: 'printing',
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self._show_(anObject);
-return self}, function($ctx1) {$ctx1.fill(self,"inspect:",{anObject:anObject},smalltalk.Transcript.klass)})},
-args: ["anObject"],
-source: "inspect: anObject\x0a\x09self show: anObject",
-messageSends: ["show:"],
-referencedClasses: []
-}),
-smalltalk.Transcript.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "new",
-category: 'instance creation',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self._shouldNotImplement();
-return self}, function($ctx1) {$ctx1.fill(self,"new",{},smalltalk.Transcript.klass)})},
-args: [],
-source: "new\x0a\x09self shouldNotImplement",
-messageSends: ["shouldNotImplement"],
-referencedClasses: []
-}),
-smalltalk.Transcript.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "open",
-category: 'instance creation',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-_st(self._current())._open();
-return self}, function($ctx1) {$ctx1.fill(self,"open",{},smalltalk.Transcript.klass)})},
-args: [],
-source: "open\x0a\x09self current open",
-messageSends: ["open", "current"],
-referencedClasses: []
-}),
-smalltalk.Transcript.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "register:",
-category: 'instance creation',
-fn: function (aTranscript){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self["@current"]=aTranscript;
-return self}, function($ctx1) {$ctx1.fill(self,"register:",{aTranscript:aTranscript},smalltalk.Transcript.klass)})},
-args: ["aTranscript"],
-source: "register: aTranscript\x0a\x09current := aTranscript",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.Transcript.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "show:",
-category: 'printing',
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-_st(self._current())._show_(anObject);
-return self}, function($ctx1) {$ctx1.fill(self,"show:",{anObject:anObject},smalltalk.Transcript.klass)})},
-args: ["anObject"],
-source: "show: anObject\x0a\x09self current show: anObject",
-messageSends: ["show:", "current"],
-referencedClasses: []
-}),
-smalltalk.Transcript.klass);
+globals.ConsoleTranscript.klass);
 
 });

+ 163 - 116
js/SUnit-Tests.js

@@ -1,146 +1,161 @@
-define("amber_core/SUnit-Tests", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/SUnit"], function(smalltalk,nil,_st){
+define("amber_core/SUnit-Tests", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/SUnit"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('SUnit-Tests');
 smalltalk.packages["SUnit-Tests"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('ExampleSetTest', smalltalk.TestCase, ['empty', 'full'], 'SUnit-Tests');
-smalltalk.ExampleSetTest.comment="ExampleSetTest is taken from Pharo 1.4.\x0a\x0aTHe purpose of this class is to demonstrate a simple use case of the test framework.";
+smalltalk.addClass('ExampleSetTest', globals.TestCase, ['empty', 'full'], 'SUnit-Tests');
+globals.ExampleSetTest.comment="ExampleSetTest is taken from Pharo 1.4.\x0a\x0aTHe purpose of this class is to demonstrate a simple use case of the test framework.";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setUp",
-category: 'running',
+protocol: 'running',
 fn: function (){
 var self=this;
-function $Set(){return smalltalk.Set||(typeof Set=="undefined"?nil:Set)}
+function $Set(){return globals.Set||(typeof Set=="undefined"?nil:Set)}
 return smalltalk.withContext(function($ctx1) { 
 self["@empty"]=_st($Set())._new();
 self["@full"]=_st($Set())._with_with_((5),"abc");
-return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},smalltalk.ExampleSetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},globals.ExampleSetTest)})},
 args: [],
 source: "setUp\x0a\x09empty := Set new.\x0a\x09full := Set with: 5 with: #abc",
 messageSends: ["new", "with:with:"],
 referencedClasses: ["Set"]
 }),
-smalltalk.ExampleSetTest);
+globals.ExampleSetTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAdd",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self["@empty"])._add_((5));
 self._assert_(_st(self["@empty"])._includes_((5)));
-return self}, function($ctx1) {$ctx1.fill(self,"testAdd",{},smalltalk.ExampleSetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testAdd",{},globals.ExampleSetTest)})},
 args: [],
 source: "testAdd\x0a\x09empty add: 5.\x0a\x09self assert: (empty includes: 5)",
 messageSends: ["add:", "assert:", "includes:"],
 referencedClasses: []
 }),
-smalltalk.ExampleSetTest);
+globals.ExampleSetTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testGrow",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self["@empty"])._addAll_((1)._to_((100)));
 self._assert_equals_(_st(self["@empty"])._size(),(100));
-return self}, function($ctx1) {$ctx1.fill(self,"testGrow",{},smalltalk.ExampleSetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testGrow",{},globals.ExampleSetTest)})},
 args: [],
 source: "testGrow\x0a\x09empty addAll: (1 to: 100).\x0a\x09self assert: empty size equals: 100",
 messageSends: ["addAll:", "to:", "assert:equals:", "size"],
 referencedClasses: []
 }),
-smalltalk.ExampleSetTest);
+globals.ExampleSetTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIllegal",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
-function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
+function $Error(){return globals.Error||(typeof Error=="undefined"?nil:Error)}
 return smalltalk.withContext(function($ctx1) { 
 self._should_raise_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self["@empty"])._at_((5));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),$Error());
+$ctx1.sendIdx["should:raise:"]=1;
 self._should_raise_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self["@empty"])._at_put_((5),"abc");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}),$Error());
-return self}, function($ctx1) {$ctx1.fill(self,"testIllegal",{},smalltalk.ExampleSetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testIllegal",{},globals.ExampleSetTest)})},
 args: [],
-source: "testIllegal\x0a\x09self\x0a\x09\x09should: [empty at: 5]\x0a\x09\x09raise: Error.\x0a\x09self\x0a\x09\x09should: [empty at: 5 put: #abc]\x0a\x09\x09raise: Error",
+source: "testIllegal\x0a\x09self\x0a\x09\x09should: [ empty at: 5 ]\x0a\x09\x09raise: Error.\x0a\x09self\x0a\x09\x09should: [ empty at: 5 put: #abc ]\x0a\x09\x09raise: Error",
 messageSends: ["should:raise:", "at:", "at:put:"],
 referencedClasses: ["Error"]
 }),
-smalltalk.ExampleSetTest);
+globals.ExampleSetTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIncludes",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_(_st(self["@full"])._includes_((5)));
+var $1;
+$1=_st(self["@full"])._includes_((5));
+$ctx1.sendIdx["includes:"]=1;
+self._assert_($1);
+$ctx1.sendIdx["assert:"]=1;
 self._assert_(_st(self["@full"])._includes_("abc"));
-return self}, function($ctx1) {$ctx1.fill(self,"testIncludes",{},smalltalk.ExampleSetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testIncludes",{},globals.ExampleSetTest)})},
 args: [],
 source: "testIncludes\x0a\x09self assert: (full includes: 5).\x0a\x09self assert: (full includes: #abc)",
 messageSends: ["assert:", "includes:"],
 referencedClasses: []
 }),
-smalltalk.ExampleSetTest);
+globals.ExampleSetTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testOccurrences",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(_st(self["@empty"])._occurrencesOf_((0)),(0));
-self._assert_equals_(_st(self["@full"])._occurrencesOf_((5)),(1));
+var $1,$2;
+$1=_st(self["@empty"])._occurrencesOf_((0));
+$ctx1.sendIdx["occurrencesOf:"]=1;
+self._assert_equals_($1,(0));
+$ctx1.sendIdx["assert:equals:"]=1;
+$2=_st(self["@full"])._occurrencesOf_((5));
+$ctx1.sendIdx["occurrencesOf:"]=2;
+self._assert_equals_($2,(1));
+$ctx1.sendIdx["assert:equals:"]=2;
 _st(self["@full"])._add_((5));
 self._assert_equals_(_st(self["@full"])._occurrencesOf_((5)),(1));
-return self}, function($ctx1) {$ctx1.fill(self,"testOccurrences",{},smalltalk.ExampleSetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testOccurrences",{},globals.ExampleSetTest)})},
 args: [],
 source: "testOccurrences\x0a\x09self assert: (empty occurrencesOf: 0) equals: 0.\x0a\x09self assert: (full occurrencesOf: 5) equals: 1.\x0a\x09full add: 5.\x0a\x09self assert: (full occurrencesOf: 5) equals: 1",
 messageSends: ["assert:equals:", "occurrencesOf:", "add:"],
 referencedClasses: []
 }),
-smalltalk.ExampleSetTest);
+globals.ExampleSetTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testRemove",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1;
 _st(self["@full"])._remove_((5));
-self._assert_(_st(self["@full"])._includes_("abc"));
+$1=_st(self["@full"])._includes_("abc");
+$ctx1.sendIdx["includes:"]=1;
+self._assert_($1);
 self._deny_(_st(self["@full"])._includes_((5)));
-return self}, function($ctx1) {$ctx1.fill(self,"testRemove",{},smalltalk.ExampleSetTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testRemove",{},globals.ExampleSetTest)})},
 args: [],
 source: "testRemove\x0a\x09full remove: 5.\x0a\x09self assert: (full includes: #abc).\x0a\x09self deny: (full includes: 5)",
 messageSends: ["remove:", "assert:", "includes:", "deny:"],
 referencedClasses: []
 }),
-smalltalk.ExampleSetTest);
+globals.ExampleSetTest);
 
 
 
-smalltalk.addClass('SUnitAsyncTest', smalltalk.TestCase, ['flag'], 'SUnit-Tests');
+smalltalk.addClass('SUnitAsyncTest', globals.TestCase, ['flag'], 'SUnit-Tests');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fakeError",
-category: 'helpers',
+protocol: 'helpers',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -152,18 +167,18 @@ self["@flag"]="ok";
 self["@flag"];
 return self._error_("Intentional");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((20));
-return self}, function($ctx1) {$ctx1.fill(self,"fakeError",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"fakeError",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "fakeError\x0a\x09flag := 'bad'.\x0a\x09self timeout: 30.\x0a\x09flag := (self async: [ flag := 'ok'. self error: 'Intentional' ]) valueWithTimeout: 20",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "error:"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fakeErrorFailingInTearDown",
-category: 'helpers',
+protocol: 'helpers',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -173,18 +188,18 @@ self["@flag"]=_st(self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._error_("Intentional");
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((20));
-return self}, function($ctx1) {$ctx1.fill(self,"fakeErrorFailingInTearDown",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"fakeErrorFailingInTearDown",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "fakeErrorFailingInTearDown\x0a\x09flag := 'bad'.\x0a\x09self timeout: 30.\x0a\x09flag := (self async: [ self error: 'Intentional' ]) valueWithTimeout: 20",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "error:"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fakeFailure",
-category: 'helpers',
+protocol: 'helpers',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -196,66 +211,76 @@ self["@flag"]="ok";
 self["@flag"];
 return self._assert_(false);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((20));
-return self}, function($ctx1) {$ctx1.fill(self,"fakeFailure",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"fakeFailure",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "fakeFailure\x0a\x09flag := 'bad'.\x0a\x09self timeout: 30.\x0a\x09flag := (self async: [ flag := 'ok'. self assert: false ]) valueWithTimeout: 20",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "assert:"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fakeMultipleTimeoutFailing",
-category: 'helpers',
+protocol: 'helpers',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1;
 self._timeout_((100));
-_st(self._async_((function(){
+$ctx1.sendIdx["timeout:"]=1;
+$1=self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
 self._timeout_((20));
 return _st(self._async_((function(){
 return smalltalk.withContext(function($ctx3) {
 return self._finished();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})})))._valueWithTimeout_((30));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((20));
-return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutFailing",{},smalltalk.SUnitAsyncTest)})},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+$ctx1.sendIdx["async:"]=1;
+_st($1)._valueWithTimeout_((20));
+$ctx1.sendIdx["valueWithTimeout:"]=1;
+return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutFailing",{},globals.SUnitAsyncTest)})},
 args: [],
-source: "fakeMultipleTimeoutFailing\x0a\x09self timeout: 100.\x0a\x09(self async: [\x0a\x09\x09self timeout: 20.\x0a\x09\x09(self async: [ self finished ]) valueWithTimeout: 30\x0a\x09]) valueWithTimeout: 20",
+source: "fakeMultipleTimeoutFailing\x0a\x09self timeout: 100.\x0a\x09(self async: [ \x0a\x09\x09self timeout: 20.\x0a\x09\x09(self async: [ self finished ]) valueWithTimeout: 30\x0a\x09]) valueWithTimeout: 20",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fakeMultipleTimeoutPassing",
-category: 'helpers',
+protocol: 'helpers',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1;
 self._timeout_((20));
-_st(self._async_((function(){
+$ctx1.sendIdx["timeout:"]=1;
+$1=self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
 self._timeout_((40));
 return _st(self._async_((function(){
 return smalltalk.withContext(function($ctx3) {
 return self._finished();
 }, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})})))._valueWithTimeout_((20));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((10));
-return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutPassing",{},smalltalk.SUnitAsyncTest)})},
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+$ctx1.sendIdx["async:"]=1;
+_st($1)._valueWithTimeout_((10));
+$ctx1.sendIdx["valueWithTimeout:"]=1;
+return self}, function($ctx1) {$ctx1.fill(self,"fakeMultipleTimeoutPassing",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "fakeMultipleTimeoutPassing\x0a\x09self timeout: 20.\x0a\x09(self async: [\x0a\x09\x09self timeout: 40.\x0a\x09\x09(self async: [ self finished ]) valueWithTimeout: 20\x0a\x09]) valueWithTimeout: 10",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "fakeTimeout",
-category: 'helpers',
+protocol: 'helpers',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -264,18 +289,18 @@ _st(self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._finished();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((20));
-return self}, function($ctx1) {$ctx1.fill(self,"fakeTimeout",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"fakeTimeout",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "fakeTimeout\x0a\x09self timeout: 10.\x0a\x09(self async: [ self finished ]) valueWithTimeout: 20",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "selectorSetOf:",
-category: 'private',
+protocol: 'private',
 fn: function (aCollection){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -285,57 +310,56 @@ return smalltalk.withContext(function($ctx2) {
 return _st(each)._selector();
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})})))._asSet();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectorSetOf:",{aCollection:aCollection},smalltalk.SUnitAsyncTest)})},
+}, function($ctx1) {$ctx1.fill(self,"selectorSetOf:",{aCollection:aCollection},globals.SUnitAsyncTest)})},
 args: ["aCollection"],
-source: "selectorSetOf: aCollection\x0a\x09^(aCollection collect: [:each | each selector]) asSet",
+source: "selectorSetOf: aCollection\x0a\x09^ (aCollection collect: [ :each | each selector ]) asSet",
 messageSends: ["asSet", "collect:", "selector"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setUp",
-category: 'running',
+protocol: 'running',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@flag"]="ok";
-return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},smalltalk.SUnitAsyncTest)})},
+return self},
 args: [],
 source: "setUp\x0a\x09flag := 'ok'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "tearDown",
-category: 'running',
+protocol: 'running',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._assert_equals_("ok",self["@flag"]);
-return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "tearDown\x0a\x09self assert: 'ok' equals: flag",
 messageSends: ["assert:equals:"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAsyncErrorsAndFailures",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 var suite,runner,result,assertBlock;
-function $TestSuiteRunner(){return smalltalk.TestSuiteRunner||(typeof TestSuiteRunner=="undefined"?nil:TestSuiteRunner)}
-function $ResultAnnouncement(){return smalltalk.ResultAnnouncement||(typeof ResultAnnouncement=="undefined"?nil:ResultAnnouncement)}
+function $TestSuiteRunner(){return globals.TestSuiteRunner||(typeof TestSuiteRunner=="undefined"?nil:TestSuiteRunner)}
+function $ResultAnnouncement(){return globals.ResultAnnouncement||(typeof ResultAnnouncement=="undefined"?nil:ResultAnnouncement)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1,$2,$3,$4;
 suite=["fakeError", "fakeErrorFailingInTearDown", "fakeFailure", "testPass"]._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(self._class())._selector_(each);
@@ -343,108 +367,120 @@ return _st(self._class())._selector_(each);
 runner=_st($TestSuiteRunner())._on_(suite);
 self._timeout_((200));
 result=_st(runner)._result();
+$ctx1.sendIdx["result"]=1;
 assertBlock=self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
-self._assert_equals_(self._selectorSetOf_(_st(result)._errors()),["fakeError"]._asSet());
+$1=self._selectorSetOf_(_st(result)._errors());
+$ctx2.sendIdx["selectorSetOf:"]=1;
+$2=["fakeError"]._asSet();
+$ctx2.sendIdx["asSet"]=1;
+self._assert_equals_($1,$2);
+$ctx2.sendIdx["assert:equals:"]=1;
 self._assert_equals_(self._selectorSetOf_(_st(result)._failures()),["fakeErrorFailingInTearDown", "fakeFailure"]._asSet());
 return self._finished();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 _st(_st(runner)._announcer())._on_do_($ResultAnnouncement(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(ann)._result()).__eq_eq(result);
-if(smalltalk.assert($1)){
-$2=_st(_st(result)._runs()).__eq(_st(result)._total());
-return _st($2)._ifTrue_(assertBlock);
+$3=_st(_st(ann)._result()).__eq_eq(result);
+if(smalltalk.assert($3)){
+$4=_st(_st(result)._runs()).__eq(_st(result)._total());
+return _st($4)._ifTrue_(assertBlock);
 };
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1,3)})}));
 _st(runner)._run();
-return self}, function($ctx1) {$ctx1.fill(self,"testAsyncErrorsAndFailures",{suite:suite,runner:runner,result:result,assertBlock:assertBlock},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testAsyncErrorsAndFailures",{suite:suite,runner:runner,result:result,assertBlock:assertBlock},globals.SUnitAsyncTest)})},
 args: [],
-source: "testAsyncErrorsAndFailures\x0a\x09| suite runner result assertBlock |\x0a\x09suite := #('fakeError' 'fakeErrorFailingInTearDown' 'fakeFailure' 'testPass') collect: [ :each | self class selector: each ].\x0a\x09runner := TestSuiteRunner on: suite.\x0a\x09self timeout: 200.\x0a\x09result := runner result.\x0a\x09assertBlock := self async: [\x0a\x09\x09self assert: (self selectorSetOf: result errors) equals: #('fakeError') asSet.\x0a\x09\x09self assert: (self selectorSetOf: result failures) equals: #('fakeErrorFailingInTearDown' 'fakeFailure') asSet.\x0a\x09\x09self finished\x0a\x09].\x0a\x09runner announcer on: ResultAnnouncement do: [:ann |\x0a\x09\x09ann result == result ifTrue: [ result runs = result total ifTrue: assertBlock ]].\x0a\x09runner run",
+source: "testAsyncErrorsAndFailures\x0a\x09| suite runner result assertBlock |\x0a\x09suite := #('fakeError' 'fakeErrorFailingInTearDown' 'fakeFailure' 'testPass') collect: [ :each | self class selector: each ].\x0a\x09runner := TestSuiteRunner on: suite.\x0a\x09self timeout: 200.\x0a\x09result := runner result.\x0a\x09assertBlock := self async: [\x0a\x09\x09self assert: (self selectorSetOf: result errors) equals: #('fakeError') asSet.\x0a\x09\x09self assert: (self selectorSetOf: result failures) equals: #('fakeErrorFailingInTearDown' 'fakeFailure') asSet.\x0a\x09\x09self finished\x0a\x09].\x0a\x09runner announcer on: ResultAnnouncement do: [ :ann |\x0a\x09\x09ann result == result ifTrue: [ result runs = result total ifTrue: assertBlock ] ].\x0a\x09runner run",
 messageSends: ["collect:", "selector:", "class", "on:", "timeout:", "result", "async:", "assert:equals:", "selectorSetOf:", "errors", "asSet", "failures", "finished", "on:do:", "announcer", "ifTrue:", "==", "=", "runs", "total", "run"],
 referencedClasses: ["TestSuiteRunner", "ResultAnnouncement"]
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAsyncNeedsTimeout",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
-function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
+function $Error(){return globals.Error||(typeof Error=="undefined"?nil:Error)}
 return smalltalk.withContext(function($ctx1) { 
 self._should_raise_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._async_((function(){
-return smalltalk.withContext(function($ctx3) {
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+}));
+$ctx2.sendIdx["async:"]=1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),$Error());
 self._timeout_((0));
 self._shouldnt_raise_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._async_((function(){
-return smalltalk.withContext(function($ctx3) {
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2,4)})}));
+}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,3)})}),$Error());
 self._finished();
-return self}, function($ctx1) {$ctx1.fill(self,"testAsyncNeedsTimeout",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testAsyncNeedsTimeout",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "testAsyncNeedsTimeout\x0a\x09self should: [ self async: [ ] ] raise: Error.\x0a\x09self timeout: 0.\x0a\x09self shouldnt: [ self async: [ ] ] raise: Error.\x0a\x09self finished",
 messageSends: ["should:raise:", "async:", "timeout:", "shouldnt:raise:", "finished"],
 referencedClasses: ["Error"]
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testFinishedNeedsTimeout",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
-function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
+function $Error(){return globals.Error||(typeof Error=="undefined"?nil:Error)}
 return smalltalk.withContext(function($ctx1) { 
 self._should_raise_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._finished();
+$ctx2.sendIdx["finished"]=1;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),$Error());
 self._timeout_((0));
 self._shouldnt_raise_((function(){
 return smalltalk.withContext(function($ctx2) {
 return self._finished();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}),$Error());
-return self}, function($ctx1) {$ctx1.fill(self,"testFinishedNeedsTimeout",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testFinishedNeedsTimeout",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "testFinishedNeedsTimeout\x0a\x09self should: [ self finished ] raise: Error.\x0a\x09self timeout: 0.\x0a\x09self shouldnt: [ self finished ] raise: Error.",
 messageSends: ["should:raise:", "finished", "timeout:", "shouldnt:raise:"],
 referencedClasses: ["Error"]
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIsAsyncReturnsCorrectValues",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._deny_(self._isAsync());
+var $1,$2;
+$1=self._isAsync();
+$ctx1.sendIdx["isAsync"]=1;
+self._deny_($1);
+$ctx1.sendIdx["deny:"]=1;
 self._timeout_((0));
-self._assert_(self._isAsync());
+$2=self._isAsync();
+$ctx1.sendIdx["isAsync"]=2;
+self._assert_($2);
 self._finished();
 self._deny_(self._isAsync());
-return self}, function($ctx1) {$ctx1.fill(self,"testIsAsyncReturnsCorrectValues",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testIsAsyncReturnsCorrectValues",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "testIsAsyncReturnsCorrectValues\x0a\x09self deny: self isAsync.\x0a\x09self timeout: 0.\x0a\x09self assert: self isAsync.\x0a\x09self finished.\x0a\x09self deny: self isAsync",
 messageSends: ["deny:", "isAsync", "timeout:", "assert:", "finished"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testPass",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -457,26 +493,26 @@ self._finished();
 self["@flag"]="ok";
 return self["@flag"];
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((5));
-return self}, function($ctx1) {$ctx1.fill(self,"testPass",{},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testPass",{},globals.SUnitAsyncTest)})},
 args: [],
 source: "testPass\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a\x09flag := (self async: [ self assert: true. self finished. flag := 'ok' ]) valueWithTimeout: 5",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "assert:", "finished"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testTimeouts",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 var suite,runner,result,assertBlock;
-function $TestSuiteRunner(){return smalltalk.TestSuiteRunner||(typeof TestSuiteRunner=="undefined"?nil:TestSuiteRunner)}
-function $Set(){return smalltalk.Set||(typeof Set=="undefined"?nil:Set)}
-function $ResultAnnouncement(){return smalltalk.ResultAnnouncement||(typeof ResultAnnouncement=="undefined"?nil:ResultAnnouncement)}
+function $TestSuiteRunner(){return globals.TestSuiteRunner||(typeof TestSuiteRunner=="undefined"?nil:TestSuiteRunner)}
+function $Set(){return globals.Set||(typeof Set=="undefined"?nil:Set)}
+function $ResultAnnouncement(){return globals.ResultAnnouncement||(typeof ResultAnnouncement=="undefined"?nil:ResultAnnouncement)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1,$2,$3;
 suite=["fakeTimeout", "fakeMultipleTimeoutFailing", "fakeMultipleTimeoutPassing", "testPass"]._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return _st(self._class())._selector_(each);
@@ -484,49 +520,60 @@ return _st(self._class())._selector_(each);
 runner=_st($TestSuiteRunner())._on_(suite);
 self._timeout_((200));
 result=_st(runner)._result();
+$ctx1.sendIdx["result"]=1;
 assertBlock=self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
-self._assert_equals_(self._selectorSetOf_(_st(result)._errors()),_st($Set())._new());
+$1=self._selectorSetOf_(_st(result)._errors());
+$ctx2.sendIdx["selectorSetOf:"]=1;
+self._assert_equals_($1,_st($Set())._new());
+$ctx2.sendIdx["assert:equals:"]=1;
 self._assert_equals_(self._selectorSetOf_(_st(result)._failures()),["fakeMultipleTimeoutFailing", "fakeTimeout"]._asSet());
 return self._finished();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
 _st(_st(runner)._announcer())._on_do_($ResultAnnouncement(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(ann)._result()).__eq_eq(result);
-if(smalltalk.assert($1)){
-$2=_st(_st(result)._runs()).__eq(_st(result)._total());
-return _st($2)._ifTrue_(assertBlock);
+$2=_st(_st(ann)._result()).__eq_eq(result);
+if(smalltalk.assert($2)){
+$3=_st(_st(result)._runs()).__eq(_st(result)._total());
+return _st($3)._ifTrue_(assertBlock);
 };
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1,3)})}));
 _st(runner)._run();
-return self}, function($ctx1) {$ctx1.fill(self,"testTimeouts",{suite:suite,runner:runner,result:result,assertBlock:assertBlock},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testTimeouts",{suite:suite,runner:runner,result:result,assertBlock:assertBlock},globals.SUnitAsyncTest)})},
 args: [],
-source: "testTimeouts\x0a\x09| suite runner result assertBlock |\x0a\x09suite := #('fakeTimeout' 'fakeMultipleTimeoutFailing' 'fakeMultipleTimeoutPassing' 'testPass') collect: [ :each | self class selector: each ].\x0a\x09runner := TestSuiteRunner on: suite.\x0a\x09self timeout: 200.\x0a\x09result := runner result.\x0a\x09assertBlock := self async: [\x0a\x09\x09self assert: (self selectorSetOf: result errors) equals: Set new.\x0a\x09\x09self assert: (self selectorSetOf: result failures) equals: #('fakeMultipleTimeoutFailing' 'fakeTimeout') asSet.\x0a\x09\x09self finished\x0a\x09].\x0a\x09runner announcer on: ResultAnnouncement do: [:ann |\x0a\x09\x09ann result == result ifTrue: [ result runs = result total ifTrue: assertBlock ]].\x0a\x09runner run",
+source: "testTimeouts\x0a\x09| suite runner result assertBlock |\x0a\x09suite := #('fakeTimeout' 'fakeMultipleTimeoutFailing' 'fakeMultipleTimeoutPassing' 'testPass') collect: [ :each | self class selector: each ].\x0a\x09runner := TestSuiteRunner on: suite.\x0a\x09self timeout: 200.\x0a\x09result := runner result.\x0a\x09assertBlock := self async: [\x0a\x09\x09self assert: (self selectorSetOf: result errors) equals: Set new.\x0a\x09\x09self assert: (self selectorSetOf: result failures) equals: #('fakeMultipleTimeoutFailing' 'fakeTimeout') asSet.\x0a\x09\x09self finished\x0a\x09].\x0a\x09runner announcer on: ResultAnnouncement do: [ :ann |\x0a\x09\x09ann result == result ifTrue: [ result runs = result total ifTrue: assertBlock ] ].\x0a\x09runner run",
 messageSends: ["collect:", "selector:", "class", "on:", "timeout:", "result", "async:", "assert:equals:", "selectorSetOf:", "errors", "new", "failures", "asSet", "finished", "on:do:", "announcer", "ifTrue:", "==", "=", "runs", "total", "run"],
 referencedClasses: ["TestSuiteRunner", "Set", "ResultAnnouncement"]
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testTwoAsyncPassesWithFinishedOnlyOneIsRun",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 var x;
 return smalltalk.withContext(function($ctx1) { 
+var $1;
 self["@flag"]="bad";
 self._timeout_((10));
 x=(0);
-self["@flag"]=_st(self._async_((function(){
+$1=self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
 self._finished();
+$ctx2.sendIdx["finished"]=1;
 self["@flag"]="ok";
 self["@flag"];
 x=_st(x).__plus((1));
+$ctx2.sendIdx["+"]=1;
 x;
 return self._assert_equals_(x,(1));
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._valueWithTimeout_((0));
+$ctx2.sendIdx["assert:equals:"]=1;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
+$ctx1.sendIdx["async:"]=1;
+self["@flag"]=_st($1)._valueWithTimeout_((0));
+$ctx1.sendIdx["valueWithTimeout:"]=1;
 self["@flag"]=_st(self._async_((function(){
 return smalltalk.withContext(function($ctx2) {
 self._finished();
@@ -536,13 +583,13 @@ x=_st(x).__plus((1));
 x;
 return self._assert_equals_(x,(1));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})})))._valueWithTimeout_((0));
-return self}, function($ctx1) {$ctx1.fill(self,"testTwoAsyncPassesWithFinishedOnlyOneIsRun",{x:x},smalltalk.SUnitAsyncTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testTwoAsyncPassesWithFinishedOnlyOneIsRun",{x:x},globals.SUnitAsyncTest)})},
 args: [],
 source: "testTwoAsyncPassesWithFinishedOnlyOneIsRun\x0a\x09| x |\x0a\x09flag := 'bad'.\x0a\x09self timeout: 10.\x0a\x09x := 0.\x0a\x09flag := (self async: [ self finished. flag := 'ok'. x := x+1. self assert: x equals: 1 ]) valueWithTimeout: 0.\x0a\x09flag := (self async: [ self finished. flag := 'ok'. x := x+1. self assert: x equals: 1 ]) valueWithTimeout: 0.",
 messageSends: ["timeout:", "valueWithTimeout:", "async:", "finished", "+", "assert:equals:"],
 referencedClasses: []
 }),
-smalltalk.SUnitAsyncTest);
+globals.SUnitAsyncTest);
 
 
 });

File diff suppressed because it is too large
+ 203 - 209
js/SUnit.js


+ 87 - 76
js/Spaces.js

@@ -1,183 +1,186 @@
-define("amber_core/Spaces", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects", "amber_core/Kernel-Exceptions", "amber_core/SUnit"], function(smalltalk,nil,_st){
+define("amber_core/Spaces", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_vm/globals", "amber_core/Kernel-Objects", "amber_core/Kernel-Exceptions", "amber_core/SUnit"], function(smalltalk,nil,_st, globals){
 smalltalk.addPackage('Spaces');
 smalltalk.packages["Spaces"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
-smalltalk.addClass('ObjectSpace', smalltalk.Object, ['frame'], 'Spaces');
-smalltalk.ObjectSpace.comment="I am a connection to another Smalltalk environment.\x0aThe implementation creates an iframe on the same location as the window, and connect to the Amber environment.\x0a\x0a\x0a\x0a## Usage example:\x0a\x0a\x09| space |\x0a\x09\x0a\x09space := ObjectSpace new.\x0a\x09space do: [ smalltalk ] \x22Answers aSmalltalk\x22\x0a\x09(space do: [ smalltalk ]) == smalltalk \x22Answers false\x22\x0a\x09\x0a\x09space release \x22Remove the object space environment\x22";
+smalltalk.addClass('ObjectSpace', globals.Object, ['frame'], 'Spaces');
+globals.ObjectSpace.comment="I am a connection to another Smalltalk environment.\x0aThe implementation creates an iframe on the same location as the window, and connect to the Amber environment.\x0a\x0a\x0a\x0a## Usage example:\x0a\x0a\x09| space |\x0a\x09\x0a\x09space := ObjectSpace new.\x0a\x09space do: [ smalltalk ] \x22Answers aSmalltalk\x22\x0a\x09(space do: [ smalltalk ]) == smalltalk \x22Answers false\x22\x0a\x09\x0a\x09space release \x22Remove the object space environment\x22";
 smalltalk.addMethod(
 smalltalk.method({
 selector: "connectTo:",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (aFrame){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._release();
 self["@frame"]=aFrame;
-return self}, function($ctx1) {$ctx1.fill(self,"connectTo:",{aFrame:aFrame},smalltalk.ObjectSpace)})},
+return self}, function($ctx1) {$ctx1.fill(self,"connectTo:",{aFrame:aFrame},globals.ObjectSpace)})},
 args: ["aFrame"],
 source: "connectTo: aFrame\x0a\x09self release.\x0a\x09frame := aFrame",
 messageSends: ["release"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "create",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st("body"._asJQuery())._append_("<iframe style=\x22display: none;\x22></iframe>");
+var $1;
+$1="body"._asJQuery();
+$ctx1.sendIdx["asJQuery"]=1;
+_st($1)._append_("<iframe style=\x22display: none;\x22></iframe>");
 self["@frame"]=_st(_st("iframe"._asJQuery())._get())._last();
 _st(_st(self["@frame"])._contentWindow())._location_(_st(window)._location());
-return self}, function($ctx1) {$ctx1.fill(self,"create",{},smalltalk.ObjectSpace)})},
+return self}, function($ctx1) {$ctx1.fill(self,"create",{},globals.ObjectSpace)})},
 args: [],
 source: "create\x0a\x09'body' asJQuery append: '<iframe style=\x22display: none;\x22></iframe>'.\x0a\x09frame := 'iframe' asJQuery get last.\x0a\x09frame contentWindow location: window location",
 messageSends: ["append:", "asJQuery", "last", "get", "location:", "contentWindow", "location"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "destroy",
-category: 'releasing',
+protocol: 'releasing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1;
 $1=self["@frame"];
 if(($receiver = $1) == nil || $receiver == null){
-$2=self;
-return $2;
+return self;
 } else {
 $1;
 };
 _st(_st(self["@frame"])._asJQuery())._remove();
 self._release();
-return self}, function($ctx1) {$ctx1.fill(self,"destroy",{},smalltalk.ObjectSpace)})},
+return self}, function($ctx1) {$ctx1.fill(self,"destroy",{},globals.ObjectSpace)})},
 args: [],
 source: "destroy\x0a\x09frame ifNil: [ ^ self ].\x0a\x09frame asJQuery remove.\x0a\x0a\x09self release",
 messageSends: ["ifNil:", "remove", "asJQuery", "release"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "do:",
-category: 'evaluating',
+protocol: 'evaluating',
 fn: function (aBlock){
 var self=this;
-function $ObjectSpaceConnectionError(){return smalltalk.ObjectSpaceConnectionError||(typeof ObjectSpaceConnectionError=="undefined"?nil:ObjectSpaceConnectionError)}
+function $ObjectSpaceConnectionError(){return globals.ObjectSpaceConnectionError||(typeof ObjectSpaceConnectionError=="undefined"?nil:ObjectSpaceConnectionError)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3;
+var $1,$2,$4,$5,$3;
 $1=self._isConnected();
 if(! smalltalk.assert($1)){
 $2=_st($ObjectSpaceConnectionError())._signal();
 return $2;
 };
-$3=_st(_st(self["@frame"])._contentWindow())._eval_(_st("(".__comma(_st(aBlock)._compiledSource())).__comma(")()"));
+$4=_st(self["@frame"])._contentWindow();
+$5=_st("(".__comma(_st(aBlock)._compiledSource())).__comma(")()");
+$ctx1.sendIdx[","]=1;
+$3=_st($4)._eval_($5);
 return $3;
-}, function($ctx1) {$ctx1.fill(self,"do:",{aBlock:aBlock},smalltalk.ObjectSpace)})},
+}, function($ctx1) {$ctx1.fill(self,"do:",{aBlock:aBlock},globals.ObjectSpace)})},
 args: ["aBlock"],
 source: "do: aBlock\x0a\x09self isConnected ifFalse: [ ^ ObjectSpaceConnectionError signal ].\x0a\x09^ frame contentWindow eval: '(', aBlock compiledSource, ')()'",
 messageSends: ["ifFalse:", "isConnected", "signal", "eval:", "contentWindow", ",", "compiledSource"],
 referencedClasses: ["ObjectSpaceConnectionError"]
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "frame",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=self["@frame"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"frame",{},smalltalk.ObjectSpace)})},
+},
 args: [],
 source: "frame\x0a\x09^ frame",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-smalltalk.ObjectSpace.superclass.fn.prototype._initialize.apply(_st(self), []);
+globals.ObjectSpace.superclass.fn.prototype._initialize.apply(_st(self), []);
 self._create();
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.ObjectSpace)})},
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},globals.ObjectSpace)})},
 args: [],
 source: "initialize\x0a\x09super initialize.\x0a\x09self create",
 messageSends: ["initialize", "create"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isConnected",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(self._frame())._notNil();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"isConnected",{},smalltalk.ObjectSpace)})},
+}, function($ctx1) {$ctx1.fill(self,"isConnected",{},globals.ObjectSpace)})},
 args: [],
 source: "isConnected\x0a\x09^ self frame notNil",
 messageSends: ["notNil", "frame"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "release",
-category: 'releasing',
+protocol: 'releasing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 self["@frame"]=nil;
-return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.ObjectSpace)})},
+return self},
 args: [],
 source: "release\x0a\x09frame := nil",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "whenReadyDo:",
-category: 'events',
+protocol: 'events',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(_st(self["@frame"])._asJQuery())._bind_do_("load",aBlock);
-return self}, function($ctx1) {$ctx1.fill(self,"whenReadyDo:",{aBlock:aBlock},smalltalk.ObjectSpace)})},
+return self}, function($ctx1) {$ctx1.fill(self,"whenReadyDo:",{aBlock:aBlock},globals.ObjectSpace)})},
 args: ["aBlock"],
 source: "whenReadyDo: aBlock\x0a\x09frame asJQuery\x0a\x09\x09bind: 'load'\x0a\x09\x09do: aBlock",
 messageSends: ["bind:do:", "asJQuery"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace);
+globals.ObjectSpace);
 
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "on:",
-category: 'instance creation',
+protocol: 'instance creation',
 fn: function (aFrame){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
@@ -187,154 +190,162 @@ _st($2)._connectTo_(aFrame);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{aFrame:aFrame},smalltalk.ObjectSpace.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:",{aFrame:aFrame},globals.ObjectSpace.klass)})},
 args: ["aFrame"],
 source: "on: aFrame\x0a\x09^ self basicNew\x0a\x09\x09connectTo: aFrame;\x0a\x09\x09yourself",
 messageSends: ["connectTo:", "basicNew", "yourself"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpace.klass);
+globals.ObjectSpace.klass);
 
 
-smalltalk.addClass('ObjectSpaceConnectionError', smalltalk.Error, [], 'Spaces');
+smalltalk.addClass('ObjectSpaceConnectionError', globals.Error, [], 'Spaces');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "messageText",
-category: 'accessing',
+protocol: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
 return "The ObjectSpace is not connected";
-}, function($ctx1) {$ctx1.fill(self,"messageText",{},smalltalk.ObjectSpaceConnectionError)})},
+},
 args: [],
 source: "messageText\x0a\x09^ 'The ObjectSpace is not connected'",
 messageSends: [],
 referencedClasses: []
 }),
-smalltalk.ObjectSpaceConnectionError);
+globals.ObjectSpaceConnectionError);
 
 
 
-smalltalk.addClass('ObjectSpaceTest', smalltalk.TestCase, ['space'], 'Spaces');
+smalltalk.addClass('ObjectSpaceTest', globals.TestCase, ['space'], 'Spaces');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "setUp",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
-function $ObjectSpace(){return smalltalk.ObjectSpace||(typeof ObjectSpace=="undefined"?nil:ObjectSpace)}
+function $ObjectSpace(){return globals.ObjectSpace||(typeof ObjectSpace=="undefined"?nil:ObjectSpace)}
 return smalltalk.withContext(function($ctx1) { 
 self["@space"]=_st($ObjectSpace())._new();
-return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},smalltalk.ObjectSpaceTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},globals.ObjectSpaceTest)})},
 args: [],
 source: "setUp\x0a\x09space := ObjectSpace new",
 messageSends: ["new"],
 referencedClasses: ["ObjectSpace"]
 }),
-smalltalk.ObjectSpaceTest);
+globals.ObjectSpaceTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "tearDown",
-category: 'initialization',
+protocol: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 _st(self["@space"])._destroy();
-return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{},smalltalk.ObjectSpaceTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{},globals.ObjectSpaceTest)})},
 args: [],
 source: "tearDown\x0a\x09space destroy",
 messageSends: ["destroy"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpaceTest);
+globals.ObjectSpaceTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testConnection",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
-function $ObjectSpaceConnectionError(){return smalltalk.ObjectSpaceConnectionError||(typeof ObjectSpaceConnectionError=="undefined"?nil:ObjectSpaceConnectionError)}
+function $ObjectSpaceConnectionError(){return globals.ObjectSpaceConnectionError||(typeof ObjectSpaceConnectionError=="undefined"?nil:ObjectSpaceConnectionError)}
 return smalltalk.withContext(function($ctx1) { 
 _st(self["@space"])._destroy();
 self._deny_(_st(self["@space"])._isConnected());
 self._should_raise_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(self["@space"])._do_((function(){
-return smalltalk.withContext(function($ctx3) {
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}),$ObjectSpaceConnectionError());
-return self}, function($ctx1) {$ctx1.fill(self,"testConnection",{},smalltalk.ObjectSpaceTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testConnection",{},globals.ObjectSpaceTest)})},
 args: [],
 source: "testConnection\x0a\x09space destroy.\x0a\x09self deny: space isConnected.\x0a\x09self should: [ space do: [] ] raise: ObjectSpaceConnectionError",
 messageSends: ["destroy", "deny:", "isConnected", "should:raise:", "do:"],
 referencedClasses: ["ObjectSpaceConnectionError"]
 }),
-smalltalk.ObjectSpaceTest);
+globals.ObjectSpaceTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testCreate",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._assert_(_st(_st(self["@space"])._frame())._notNil());
+$ctx1.sendIdx["assert:"]=1;
 self._assert_(_st(self["@space"])._isConnected());
-return self}, function($ctx1) {$ctx1.fill(self,"testCreate",{},smalltalk.ObjectSpaceTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testCreate",{},globals.ObjectSpaceTest)})},
 args: [],
 source: "testCreate\x0a\x0a\x09self assert: space frame notNil.\x0a\x09self assert: space isConnected",
 messageSends: ["assert:", "notNil", "frame", "isConnected"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpaceTest);
+globals.ObjectSpaceTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testEvaluation",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 var result;
-function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
+function $Smalltalk(){return globals.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
 _st(self["@space"])._whenReadyDo_((function(){
 return smalltalk.withContext(function($ctx2) {
 result=_st(self["@space"])._do_((function(){
-return smalltalk.withContext(function($ctx3) {
 return smalltalk;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2,2)})}));
+}));
 result;
-self._assert_equals_(_st(_st(result)._class())._name(),"Smalltalk");
+$2=_st(result)._class();
+$ctx2.sendIdx["class"]=1;
+$1=_st($2)._name();
+self._assert_equals_($1,"Smalltalk");
 self._deny_(_st(_st(result)._class()).__eq($Smalltalk()));
+$ctx2.sendIdx["deny:"]=1;
 return self._deny_(_st(result).__eq_eq(smalltalk));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"testEvaluation",{result:result},smalltalk.ObjectSpaceTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testEvaluation",{result:result},globals.ObjectSpaceTest)})},
 args: [],
 source: "testEvaluation\x0a\x09| result |\x0a\x0a\x09space whenReadyDo: [\x0a\x09\x09result := space do: [ smalltalk ].\x0a\x0a\x09\x09self assert: result class name equals: 'Smalltalk'.\x0a\x09\x09self deny: result class = Smalltalk.\x0a\x09\x09self deny: result == smalltalk ]",
 messageSends: ["whenReadyDo:", "do:", "assert:equals:", "name", "class", "deny:", "=", "=="],
 referencedClasses: ["Smalltalk"]
 }),
-smalltalk.ObjectSpaceTest);
+globals.ObjectSpaceTest);
 
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testRelease",
-category: 'tests',
+protocol: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._deny_(_st(_st(self["@space"])._frame())._isNil());
+var $2,$1;
+$2=_st(self["@space"])._frame();
+$ctx1.sendIdx["frame"]=1;
+$1=_st($2)._isNil();
+$ctx1.sendIdx["isNil"]=1;
+self._deny_($1);
 _st(self["@space"])._release();
 self._assert_(_st(_st(self["@space"])._frame())._isNil());
-return self}, function($ctx1) {$ctx1.fill(self,"testRelease",{},smalltalk.ObjectSpaceTest)})},
+return self}, function($ctx1) {$ctx1.fill(self,"testRelease",{},globals.ObjectSpaceTest)})},
 args: [],
 source: "testRelease\x0a\x0a\x09self deny: space frame isNil.\x0a\x0a\x09space release.\x0a\x09\x0a\x09self assert: space frame isNil",
 messageSends: ["deny:", "isNil", "frame", "release", "assert:"],
 referencedClasses: []
 }),
-smalltalk.ObjectSpaceTest);
+globals.ObjectSpaceTest);
 
 
 });

+ 7 - 4
package.json

@@ -1,6 +1,6 @@
 {
   "name": "amber",
-  "version": "0.12.0-pre",
+  "version": "0.13.0-pre",
   "description": "An implementation of the Smalltalk language that runs on top of the JS runtime.",
   "homepage": "http://amber-lang.net",
   "keywords": [
@@ -26,14 +26,17 @@
     "node": ">=0.8.0"
   },
   "bin": {
-    "amber": "./bin/amber-cli.js",
-    "amberc": "./bin/amberc"
+    "amber": "./cli/support/amber-cli.js",
+    "amberc": "./cli/support/amberc-cli.js"
   },
   "scripts": {
     "test": "grunt amberc:amber_test_runner && node ./test/amber_test_runner.js"
   },
+  "dependencies": {
+    "es6-promise": "~0.1.1"
+  },
   "devDependencies": {
-    "pegjs": "~0.7.0",
+    "pegjs": "~0.8.0",
     "grunt": "~0.4.0",
     "grunt-contrib-jshint": "~0.3.0",
     "amdefine": "0.0.8"

+ 1 - 1
st/Benchfib.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Benchfib'!
+Smalltalk createPackage: 'Benchfib'!
 Object subclass: #Benchfib
 	instanceVariableNames: ''
 	package: 'Benchfib'!

+ 155 - 211
st/Canvas.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Canvas'!
+Smalltalk createPackage: 'Canvas'!
 Object subclass: #BrowserInterface
 	instanceVariableNames: ''
 	package: 'Canvas'!
@@ -20,19 +20,19 @@ I am platform interface class that tries to use window and jQuery; that is, one
 !BrowserInterface methodsFor: 'actions'!
 
 ajax: anObject
-	^jQuery ajax: anObject
+	^ jQuery ajax: anObject
 !
 
 alert: aString
-	^window alert: aString
+	^ window alert: aString
 !
 
 confirm: aString
-	^window confirm: aString
+	^ window confirm: aString
 !
 
 prompt: aString
-	^window prompt: aString
+	^ window prompt: aString
 ! !
 
 !BrowserInterface methodsFor: 'testing'!
@@ -41,8 +41,6 @@ isAvailable
 <return typeof window !!== "undefined" && typeof jQuery !!== "undefined">
 ! !
 
-BrowserInterface class instanceVariableNames: 'uiWorker ajaxWorker'!
-
 Object subclass: #HTMLCanvas
 	instanceVariableNames: 'root'
 	package: 'Canvas'!
@@ -66,7 +64,7 @@ The `#with:` method is used to compose HTML, nesting tags. `#with:` can take a `
 !HTMLCanvas methodsFor: 'accessing'!
 
 root
-	^root
+	^ root
 !
 
 root: aTagBrush
@@ -86,7 +84,7 @@ snippet: anElement
 	self with: (TagBrush fromJQuery: clone canvas: self).
 	caret := clone find: '[data-snippet="*"]'.
 	caret toArray isEmpty ifTrue: [ caret := clone ].
-	^TagBrush fromJQuery: (caret removeAttr: 'data-snippet') canvas: self
+	^ TagBrush fromJQuery: (caret removeAttr: 'data-snippet') canvas: self
 ! !
 
 !HTMLCanvas methodsFor: 'adding'!
@@ -103,14 +101,14 @@ entity: aString
 !
 
 with: anObject
-	^self root with: anObject
+	^ self root with: anObject
 ! !
 
 !HTMLCanvas methodsFor: 'initialization'!
 
 initialize
 	super initialize.
-	root ifNil: [root := TagBrush fromString: 'div' canvas: self]
+	root ifNil: [ root := TagBrush fromString: 'div' canvas: self ]
 !
 
 initializeFromJQuery: aJQuery
@@ -120,151 +118,151 @@ initializeFromJQuery: aJQuery
 !HTMLCanvas methodsFor: 'tags'!
 
 a
-	^self tag: 'a'
+	^ self tag: 'a'
 !
 
 abbr
-	^self tag: 'abbr'
+	^ self tag: 'abbr'
 !
 
 address
-	^self tag: 'address'
+	^ self tag: 'address'
 !
 
 area
-	^self tag: 'area'
+	^ self tag: 'area'
 !
 
 article
-	^self tag: 'article'
+	^ self tag: 'article'
 !
 
 aside
-	^self tag: 'aside'
+	^ self tag: 'aside'
 !
 
 audio
-	^self tag: 'audio'
+	^ self tag: 'audio'
 !
 
 base
-	^self tag: 'base'
+	^ self tag: 'base'
 !
 
 blockquote
-	^self tag: 'blockquote'
+	^ self tag: 'blockquote'
 !
 
 body
-	^self tag: 'body'
+	^ self tag: 'body'
 !
 
 br
-	^self tag: 'br'
+	^ self tag: 'br'
 !
 
 button
-	^self tag: 'button'
+	^ self tag: 'button'
 !
 
 canvas
-	^self tag: 'canvas'
+	^ self tag: 'canvas'
 !
 
 caption
-	^self tag: 'caption'
+	^ self tag: 'caption'
 !
 
 cite
-	^self tag: 'cite'
+	^ self tag: 'cite'
 !
 
 code
-	^self tag: 'code'
+	^ self tag: 'code'
 !
 
 col
-	^self tag: 'col'
+	^ self tag: 'col'
 !
 
 colgroup
-	^self tag: 'colgroup'
+	^ self tag: 'colgroup'
 !
 
 command
-	^self tag: 'command'
+	^ self tag: 'command'
 !
 
 datalist
-	^self tag: 'datalist'
+	^ self tag: 'datalist'
 !
 
 dd
-	^self tag: 'dd'
+	^ self tag: 'dd'
 !
 
 del
-	^self tag: 'del'
+	^ self tag: 'del'
 !
 
 details
-	^self tag: 'details'
+	^ self tag: 'details'
 !
 
 div
-	^self tag: 'div'
+	^ self tag: 'div'
 !
 
 div: aBlock
-	^self div with: aBlock
+	^ self div with: aBlock
 !
 
 dl
-	^self tag: 'dl'
+	^ self tag: 'dl'
 !
 
 dt
-	^self tag: 'dt'
+	^ self tag: 'dt'
 !
 
 em
-	^self tag: 'em'
+	^ self tag: 'em'
 !
 
 embed
-	^self tag: 'embed'
+	^ self tag: 'embed'
 !
 
 fieldset
-	^self tag: 'fieldset'
+	^ self tag: 'fieldset'
 !
 
 figcaption
-	^self tag: 'figcaption'
+	^ self tag: 'figcaption'
 !
 
 figure
-	^self tag: 'figure'
+	^ self tag: 'figure'
 !
 
 footer
-	^self tag: 'footer'
+	^ self tag: 'footer'
 !
 
 form
-	^self tag: 'form'
+	^ self tag: 'form'
 !
 
 h1
-	^self tag: 'h1'
+	^ self tag: 'h1'
 !
 
 h1: anObject
-	^self h1 with: anObject
+	^ self h1 with: anObject
 !
 
 h2
-	^self tag: 'h2'
+	^ self tag: 'h2'
 !
 
 h2: anObject
@@ -272,207 +270,207 @@ h2: anObject
 !
 
 h3
-	^self tag: 'h3'
+	^ self tag: 'h3'
 !
 
 h3: anObject
-	^self h3 with: anObject
+	^ self h3 with: anObject
 !
 
 h4
-	^self tag: 'h4'
+	^ self tag: 'h4'
 !
 
 h4: anObject
-	^self h4 with: anObject
+	^ self h4 with: anObject
 !
 
 h5
-	^self tag: 'h5'
+	^ self tag: 'h5'
 !
 
 h5: anObject
-	^self h5 with: anObject
+	^ self h5 with: anObject
 !
 
 h6
-	^self tag: 'h6'
+	^ self tag: 'h6'
 !
 
 h6: anObject
-	^self h6 with: anObject
+	^ self h6 with: anObject
 !
 
 head
-	^self tag: 'head'
+	^ self tag: 'head'
 !
 
 header
-	^self tag: 'header'
+	^ self tag: 'header'
 !
 
 hgroup
-	^self tag: 'hgroup'
+	^ self tag: 'hgroup'
 !
 
 hr
-	^self tag: 'hr'
+	^ self tag: 'hr'
 !
 
 html
-	^self tag: 'html'
+	^ self tag: 'html'
 !
 
 iframe
-	^self tag: 'iframe'
+	^ self tag: 'iframe'
 !
 
 iframe: aString
-	^self iframe src: aString
+	^ self iframe src: aString
 !
 
 img
-	^self tag: 'img'
+	^ self tag: 'img'
 !
 
 img: aString
-	^self img src: aString
+	^ self img src: aString
 !
 
 input
-	^self tag: 'input'
+	^ self tag: 'input'
 !
 
 label
-	^self tag: 'label'
+	^ self tag: 'label'
 !
 
 legend
-	^self tag: 'legend'
+	^ self tag: 'legend'
 !
 
 li
-	^self tag: 'li'
+	^ self tag: 'li'
 !
 
 li: anObject
-	^self li with: anObject
+	^ self li with: anObject
 !
 
 link
-	^self tag: 'link'
+	^ self tag: 'link'
 !
 
 map
-	^self tag: 'map'
+	^ self tag: 'map'
 !
 
 mark
-	^self tag: 'mark'
+	^ self tag: 'mark'
 !
 
 menu
-	^self tag: 'menu'
+	^ self tag: 'menu'
 !
 
 meta
-	^self tag: 'meta'
+	^ self tag: 'meta'
 !
 
 nav
-	^self tag: 'nav'
+	^ self tag: 'nav'
 !
 
 newTag: aString
-	^TagBrush fromString: aString canvas: self
+	^ TagBrush fromString: aString canvas: self
 !
 
 noscript
-	^self tag: 'noscript'
+	^ self tag: 'noscript'
 !
 
 object
-	^self tag: 'object'
+	^ self tag: 'object'
 !
 
 ol
-	^self tag: 'ol'
+	^ self tag: 'ol'
 !
 
 ol: anObject
-	^self ol with: anObject
+	^ self ol with: anObject
 !
 
 optgroup
-	^self tag: 'optgroup'
+	^ self tag: 'optgroup'
 !
 
 option
-	^self tag: 'option'
+	^ self tag: 'option'
 !
 
 output
-	^self tag: 'output'
+	^ self tag: 'output'
 !
 
 p
-	^self tag: 'p'
+	^ self tag: 'p'
 !
 
 p: anObject
-	^self p with: anObject
+	^ self p with: anObject
 !
 
 param
-	^self tag: 'param'
+	^ self tag: 'param'
 !
 
 pre
-	^self tag: 'pre'
+	^ self tag: 'pre'
 !
 
 progress
-	^self tag: 'progress'
+	^ self tag: 'progress'
 !
 
 script
-	^self tag: 'script'
+	^ self tag: 'script'
 !
 
 section
-	^self tag: 'section'
+	^ self tag: 'section'
 !
 
 select
-	^self tag: 'select'
+	^ self tag: 'select'
 !
 
 small
-	^self tag: 'small'
+	^ self tag: 'small'
 !
 
 source
-	^self tag: 'source'
+	^ self tag: 'source'
 !
 
 span
-	^self tag: 'span'
+	^ self tag: 'span'
 !
 
 span: anObject
-	^self span with: anObject
+	^ self span with: anObject
 !
 
 strong
-	^self tag: 'strong'
+	^ self tag: 'strong'
 !
 
 strong: anObject
-	^self strong with: anObject
+	^ self strong with: anObject
 !
 
 style
-	^ root addBrush: (StyleTag canvas: self)
+	^ self tag: 'style'
 !
 
 style: aString
@@ -480,97 +478,86 @@ style: aString
 !
 
 sub
-	^self tag: 'sub'
+	^ self tag: 'sub'
 !
 
 summary
-	^self tag: 'summary'
+	^ self tag: 'summary'
 !
 
 sup
-	^self tag: 'sup'
+	^ self tag: 'sup'
 !
 
 table
-	^self tag: 'table'
+	^ self tag: 'table'
 !
 
 tag: aString
-	^root addBrush: (self newTag: aString)
+	^ root addBrush: (self newTag: aString)
 !
 
 tbody
-	^self tag: 'tbody'
+	^ self tag: 'tbody'
 !
 
 td
-	^self tag: 'td'
+	^ self tag: 'td'
 !
 
 textarea
-	^self tag: 'textarea'
+	^ self tag: 'textarea'
 !
 
 tfoot
-	^self tag: 'tfoot'
+	^ self tag: 'tfoot'
 !
 
 th
-	^self tag: 'th'
+	^ self tag: 'th'
 !
 
 thead
-	^self tag: 'thead'
+	^ self tag: 'thead'
 !
 
 time
-	^self tag: 'time'
+	^ self tag: 'time'
 !
 
 title
-	^self tag: 'title'
+	^ self tag: 'title'
 !
 
 tr
-	^self tag: 'tr'
+	^ self tag: 'tr'
 !
 
 ul
-	^self tag: 'ul'
+	^ self tag: 'ul'
 !
 
 ul: anObject
-	^self ul with: anObject
+	^ self ul with: anObject
 !
 
 video
-	^self tag: 'video'
+	^ self tag: 'video'
 ! !
 
-!HTMLCanvas class methodsFor: 'instance creation'!
-
-browserVersion
-	^(jQuery at: #browser) version
-!
-
-isMSIE
-	^((jQuery at: #browser) at: #msie) notNil
-!
-
-isMozilla
-	^((jQuery at: #browser) at: #mozilla) notNil
-!
+!HTMLCanvas class methodsFor: 'initialization'!
 
-isOpera
-	^((jQuery at: #browser) at: #opera) notNil
-!
+initialize
+	"Allow JS method calls for the jQuery object.
+	See boot.js DNU handling."
+	
+	jQuery basicAt: 'allowJavaScriptCalls' put: true
+! !
 
-isWebkit
-	^((jQuery at: #browser) at: #webkit) notNil
-!
+!HTMLCanvas class methodsFor: 'instance creation'!
 
 onJQuery: aJQuery
-	^self basicNew
+	^ self basicNew
 		initializeFromJQuery: aJQuery;
 		initialize;
 		yourself
@@ -624,7 +611,7 @@ snippetAt: aString
 !
 
 snippets
-	^snippets ifNil: [ snippets := #{} ]
+	^ snippets ifNil: [ snippets := #{} ]
 ! !
 
 !HTMLSnippet methodsFor: 'initialization'!
@@ -647,7 +634,7 @@ snippetAt: aString compile: anElement
 		installMethod: ([ :htmlReceiver | htmlReceiver snippet: anElement ]
 			currySelf asCompiledMethod: aString)
 		forClass: HTMLCanvas
-		category: '**snippets'
+		protocol: '**snippets'
 ! !
 
 !HTMLSnippet methodsFor: 'private'!
@@ -748,14 +735,14 @@ All tags but `<style>` are instances of me (see the `StyleBrush` class).
 !TagBrush methodsFor: 'accessing'!
 
 element
-	^element
+	^ element
 ! !
 
 !TagBrush methodsFor: 'adding'!
 
 addBrush: aTagBrush
 	self appendChild: aTagBrush element.
-	^aTagBrush
+	^ aTagBrush
 !
 
 append: anObject
@@ -820,8 +807,16 @@ alt: aString
 	self at: 'alt' put: aString
 !
 
+at: aString
+	^ self at: aString ifAbsent: [ Collection new errorNotFound ]
+!
+
+at: aString ifAbsent: aBlock
+	<return self['@element'].hasAttribute(aString) ? self['@element'].getAttribute(aString) : aBlock._value()>
+!
+
 at: aString put: aValue
-	<self['@element'].setAttribute(aString, aValue)>
+	<self['@element'].setAttribute(aString, aValue); return aValue>
 !
 
 class: aString
@@ -931,7 +926,7 @@ width: aString
 !TagBrush methodsFor: 'converting'!
 
 asJQuery
-	^self element asJQuery
+	^ self element asJQuery
 ! !
 
 !TagBrush methodsFor: 'events'!
@@ -1049,65 +1044,14 @@ createTextNodeFor: aString
 !TagBrush class methodsFor: 'instance creation'!
 
 fromJQuery: aJQuery canvas: aCanvas
-	^self new
+	^ self new
 		initializeFromJQuery: aJQuery canvas: aCanvas;
 		yourself
 !
 
 fromString: aString canvas: aCanvas
-	^self new
-	initializeFromString: aString canvas: aCanvas;
-	yourself
-! !
-
-TagBrush subclass: #DocumentFragmentTag
-	instanceVariableNames: ''
-	package: 'Canvas'!
-
-!DocumentFragmentTag methodsFor: 'initialization'!
-
-initializeFromCanvas: aCanvas
-	canvas := aCanvas.
-	element := self createDocumentFragment
-! !
-
-!DocumentFragmentTag methodsFor: 'private'!
-
-createDocumentFragment
-	<return document.createDocumentFragment()>
-! !
-
-!DocumentFragmentTag class methodsFor: 'instance creation'!
-
-canvas: aCanvas
 	^ self new
-		initializeFromCanvas: aCanvas;
-		yourself
-! !
-
-TagBrush subclass: #StyleTag
-	instanceVariableNames: ''
-	package: 'Canvas'!
-!StyleTag commentStamp!
-I'm a `<style>` tag use to inline CSS or load a stylesheet.
-
-## Motivation
-
-The need for a specific class comes from Internet Explorer compatibility issues.!
-
-!StyleTag methodsFor: 'adding'!
-
-with: aString
-	HTMLCanvas isMSIE
-		ifTrue: [self element styleSheet cssText: aString ]
-		ifFalse: [super with: aString ].
-! !
-
-!StyleTag class methodsFor: 'instance creation'!
-
-canvas: aCanvas
-	^self new
-	initializeFromString: 'style' canvas: aCanvas;
+	initializeFromString: aString canvas: aCanvas;
 	yourself
 ! !
 
@@ -1149,16 +1093,6 @@ heliosClass
 	^ 'widget'
 ! !
 
-!Object methodsFor: '*Canvas'!
-
-appendToBrush: aTagBrush
-	aTagBrush append: self asString
-!
-
-appendToJQuery: aJQuery
-	aJQuery append: self asString
-! !
-
 !BlockClosure methodsFor: '*Canvas'!
 
 appendToBrush: aTagBrush
@@ -1175,6 +1109,22 @@ asSnippet
 	^ HTMLSnippet current snippetAt: self asString
 ! !
 
+!JSObjectProxy methodsFor: '*Canvas'!
+
+asJQuery
+	<return jQuery(self['@jsObject'])>
+! !
+
+!Object methodsFor: '*Canvas'!
+
+appendToBrush: aTagBrush
+	aTagBrush append: self asString
+!
+
+appendToJQuery: aJQuery
+	aJQuery append: self asString
+! !
+
 !String methodsFor: '*Canvas'!
 
 appendToBrush: aTagBrush
@@ -1189,9 +1139,3 @@ asJQuery
 	<return jQuery(String(self))>
 ! !
 
-!JSObjectProxy methodsFor: '*Canvas'!
-
-asJQuery
-	<return jQuery(self['@jsObject'])>
-! !
-

+ 150 - 69
st/Compiler-AST.st

@@ -1,6 +1,6 @@
-Smalltalk current createPackage: 'Compiler-AST'!
+Smalltalk createPackage: 'Compiler-AST'!
 Object subclass: #Node
-	instanceVariableNames: 'parent position nodes shouldBeInlined shouldBeAliased'
+	instanceVariableNames: 'parent position source nodes shouldBeInlined shouldBeAliased'
 	package: 'Compiler-AST'!
 !Node commentStamp!
 I am the abstract root class of the abstract syntax tree.
@@ -16,6 +16,10 @@ addNode: aNode
 	aNode parent: self
 !
 
+method
+	^ self parent ifNotNil: [ :node | node method ]
+!
+
 nextChild
 	"Answer the next node after aNode.
 	Recurse into the possible children of the receiver to answer the next node to be evaluated"
@@ -44,7 +48,7 @@ nextNode: aNode
 !
 
 nodes
-	^nodes ifNil: [nodes := Array new]
+	^ nodes ifNil: [ nodes := Array new ]
 !
 
 parent
@@ -62,6 +66,18 @@ position
 		self parent ifNotNil: [ :node | node position ] ]
 !
 
+position: aPosition
+	position := aPosition
+!
+
+positionEnd
+	^ self positionStart + ((self source lines size - 1) @ (self source lines last size - 1))
+!
+
+positionStart
+	^ self position
+!
+
 shouldBeAliased
 	^ shouldBeAliased ifNil: [ false ]
 !
@@ -76,6 +92,18 @@ shouldBeInlined
 
 shouldBeInlined: aBoolean
 	shouldBeInlined := aBoolean
+!
+
+size
+	^ self source size
+!
+
+source
+	^ source ifNil: [ '' ]
+!
+
+source: aString
+	source := aString
 ! !
 
 !Node methodsFor: 'building'!
@@ -83,10 +111,6 @@ shouldBeInlined: aBoolean
 nodes: aCollection
 	nodes := aCollection.
 	aCollection do: [ :each | each parent: self ]
-!
-
-position: aPosition
-	position := aPosition
 ! !
 
 !Node methodsFor: 'copying'!
@@ -103,11 +127,11 @@ isAssignmentNode
 !
 
 isBlockNode
-	^false
+	^ false
 !
 
 isBlockSequenceNode
-	^false
+	^ false
 !
 
 isCascadeNode
@@ -115,7 +139,7 @@ isCascadeNode
 !
 
 isImmutable
-	^false
+	^ false
 !
 
 isJSStatementNode
@@ -130,16 +154,44 @@ isNode
 	^ true
 !
 
+isReferenced
+	"Answer true if the receiver is referenced by other nodes.
+	Do not take sequences or assignments into account"
+	
+	^ (self parent isSequenceNode or: [
+		self parent isAssignmentNode ]) not
+!
+
 isReturnNode
-	^false
+	^ false
 !
 
 isSendNode
-	^false
+	^ false
+!
+
+isSequenceNode
+	^ false
 !
 
 isValueNode
-	^false
+	^ false
+!
+
+isVariableNode
+	^ false
+!
+
+requiresSmalltalkContext
+	"Answer true if the receiver requires a smalltalk context.
+	Only send nodes require a context.
+	
+	If no node requires a context, the method will be compiled without one.
+	See `IRJSTranslator` and `JSStream` for context creation"
+	
+	^ (self nodes 
+		detect: [ :each | each requiresSmalltalkContext ]
+		ifNone: [ nil ]) notNil
 !
 
 stopOnStepping
@@ -147,8 +199,8 @@ stopOnStepping
 !
 
 subtreeNeedsAliasing
-	^(self shouldBeAliased or: [ self shouldBeInlined ]) or: [
-		(self nodes detect: [ :each | each subtreeNeedsAliasing ] ifNone: [ false ]) ~= false ]
+	^ (self shouldBeAliased or: [ self shouldBeInlined ]) or: [
+		self nodes anySatisfy: [ :each | each subtreeNeedsAliasing ] ]
 ! !
 
 !Node methodsFor: 'visiting'!
@@ -166,7 +218,7 @@ I represent an assignment node.!
 !AssignmentNode methodsFor: 'accessing'!
 
 left
-	^left
+	^ left
 !
 
 left: aNode
@@ -179,7 +231,7 @@ nodes
 !
 
 right
-	^right
+	^ right
 !
 
 right: aNode
@@ -191,6 +243,10 @@ right: aNode
 
 isAssignmentNode
 	^ true
+!
+
+shouldBeAliased
+	^ super shouldBeAliased or: [ self isReferenced ]
 ! !
 
 !AssignmentNode methodsFor: 'visiting'!
@@ -220,7 +276,7 @@ nextNode: aNode
 !
 
 parameters
-	^parameters ifNil: [parameters := Array new]
+	^ parameters ifNil: [ parameters := Array new ]
 !
 
 parameters: aCollection
@@ -238,7 +294,7 @@ scope: aLexicalScope
 !BlockNode methodsFor: 'testing'!
 
 isBlockNode
-	^true
+	^ true
 !
 
 subtreeNeedsAliasing
@@ -260,7 +316,7 @@ I represent an cascade node.!
 !CascadeNode methodsFor: 'accessing'!
 
 receiver
-	^receiver
+	^ receiver
 !
 
 receiver: aNode
@@ -304,25 +360,19 @@ accept: aVisitor
 ! !
 
 Node subclass: #JSStatementNode
-	instanceVariableNames: 'source'
+	instanceVariableNames: ''
 	package: 'Compiler-AST'!
 !JSStatementNode commentStamp!
 I represent an JavaScript statement node.!
 
-!JSStatementNode methodsFor: 'accessing'!
-
-source
-	^source ifNil: ['']
-!
-
-source: aString
-	source := aString
-! !
-
 !JSStatementNode methodsFor: 'testing'!
 
 isJSStatementNode
 	^ true
+!
+
+requiresSmalltalkContext
+	^ true
 ! !
 
 !JSStatementNode methodsFor: 'visiting'!
@@ -332,7 +382,7 @@ accept: aVisitor
 ! !
 
 Node subclass: #MethodNode
-	instanceVariableNames: 'selector arguments source scope classReferences messageSends superSends'
+	instanceVariableNames: 'selector arguments source scope classReferences sendIndexes superSends'
 	package: 'Compiler-AST'!
 !MethodNode commentStamp!
 I represent an method node.
@@ -342,7 +392,7 @@ A method node must be the root and only method node of a valid AST.!
 !MethodNode methodsFor: 'accessing'!
 
 arguments
-	^arguments ifNil: [#()]
+	^ arguments ifNil: [ #() ]
 !
 
 arguments: aCollection
@@ -357,16 +407,12 @@ classReferences: aCollection
 	classReferences := aCollection
 !
 
-extent
-	^ self source lines size @ (self source lines last size + 1)
-!
-
 messageSends
-	^ messageSends
+	^ self sendIndexes keys
 !
 
-messageSends: aCollection
-	messageSends := aCollection
+method
+	^ self
 !
 
 scope
@@ -378,15 +424,23 @@ scope: aMethodScope
 !
 
 selector
-	^selector
+	^ selector
 !
 
 selector: aString
 	selector := aString
 !
 
+sendIndexes
+	^ sendIndexes
+!
+
+sendIndexes: aDictionary
+	sendIndexes := aDictionary
+!
+
 source
-	^source
+	^ source
 !
 
 source: aString
@@ -448,7 +502,7 @@ I represent an message send node.!
 !SendNode methodsFor: 'accessing'!
 
 arguments
-	^arguments ifNil: [arguments := #()]
+	^ arguments ifNil: [ arguments := #() ]
 !
 
 arguments: aCollection
@@ -462,7 +516,7 @@ cascadeNodeWithMessages: aCollection
 		selector: self selector;
 		arguments: self arguments;
 		yourself.
-	^CascadeNode new
+	^ CascadeNode new
 		receiver: self receiver;
 		nodes: (Array with: first), aCollection;
 		yourself
@@ -485,7 +539,7 @@ nodes
 !
 
 receiver
-	^receiver
+	^ receiver
 !
 
 receiver: aNode
@@ -495,7 +549,7 @@ receiver: aNode
 !
 
 selector
-	^selector
+	^ selector
 !
 
 selector: aString
@@ -511,11 +565,12 @@ superSend: aBoolean
 !
 
 valueForReceiver: anObject
-	^SendNode new
+	^ SendNode new
 		position: self position;
+		source: self source;
 		receiver: (self receiver
-		ifNil: [anObject]
-		ifNotNil: [self receiver valueForReceiver: anObject]);
+		ifNil: [ anObject ] 
+		ifNotNil: [ self receiver valueForReceiver: anObject ]);
 		selector: self selector;
 		arguments: self arguments;
 		yourself
@@ -531,6 +586,22 @@ isSendNode
 	^ true
 !
 
+requiresSmalltalkContext
+	^ true
+!
+
+shouldBeAliased
+	"Because we keep track of send indexes, some send nodes need additional care for aliasing. 
+	See IRJSVisitor >> visitIRSend:"
+	
+	| sends |
+	
+	sends := (self method sendIndexes at: self selector) size.
+	
+	^ super shouldBeAliased or: [
+		(sends > 1 and: [ self index < sends ]) and: [ self isReferenced ] ]
+!
+
 stopOnStepping
 	^ true
 ! !
@@ -558,23 +629,30 @@ scope: aLexicalScope
 !
 
 temps
-	^temps ifNil: [#()]
+	^ temps ifNil: [ #() ]
 !
 
 temps: aCollection
 	temps := aCollection
 ! !
 
-!SequenceNode methodsFor: 'testing'!
+!SequenceNode methodsFor: 'converting'!
 
 asBlockSequenceNode
-	^BlockSequenceNode new
+	^ BlockSequenceNode new
 		position: self position;
+		source: self source;
 		nodes: self nodes;
 		temps: self temps;
 		yourself
 ! !
 
+!SequenceNode methodsFor: 'testing'!
+
+isSequenceNode
+	^ true
+! !
+
 !SequenceNode methodsFor: 'visiting'!
 
 accept: aVisitor
@@ -590,7 +668,7 @@ I represent an special sequence node for block scopes.!
 !BlockSequenceNode methodsFor: 'testing'!
 
 isBlockSequenceNode
-	^true
+	^ true
 ! !
 
 !BlockSequenceNode methodsFor: 'visiting'!
@@ -608,7 +686,7 @@ I represent a value node.!
 !ValueNode methodsFor: 'accessing'!
 
 value
-	^value
+	^ value
 !
 
 value: anObject
@@ -622,7 +700,7 @@ isImmutable
 !
 
 isValueNode
-	^true
+	^ true
 ! !
 
 !ValueNode methodsFor: 'visiting'!
@@ -631,11 +709,6 @@ accept: aVisitor
 	^ aVisitor visitValueNode: self
 ! !
 
-!ValueNode methodsFor: 'xxxDoIt'!
-
-xxxDoIt ^[self stack] value
-! !
-
 ValueNode subclass: #VariableNode
 	instanceVariableNames: 'assigned binding'
 	package: 'Compiler-AST'!
@@ -649,7 +722,7 @@ alias
 !
 
 assigned
-	^assigned ifNil: [false]
+	^ assigned ifNil: [ false ]
 !
 
 assigned: aBoolean
@@ -671,8 +744,16 @@ binding: aScopeVar
 
 !VariableNode methodsFor: 'testing'!
 
+isArgument
+	^ self binding isArgVar
+!
+
 isImmutable
-	^false
+	^ self binding isImmutable
+!
+
+isVariableNode
+	^ true
 ! !
 
 !VariableNode methodsFor: 'visiting'!
@@ -681,17 +762,17 @@ accept: aVisitor
 	^ aVisitor visitVariableNode: self
 ! !
 
-!Object methodsFor: '*Compiler-AST'!
-
-isNode
-	^ false
-! !
-
 !CompiledMethod methodsFor: '*Compiler-AST'!
 
 ast
 	self source ifEmpty: [ self error: 'Method source is empty' ].
 	
-	^ Smalltalk current parse: self source
+	^ Smalltalk parse: self source
+! !
+
+!Object methodsFor: '*Compiler-AST'!
+
+isNode
+	^ false
 ! !
 

+ 47 - 37
st/Compiler-Core.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Core'!
+Smalltalk createPackage: 'Compiler-Core'!
 Object subclass: #AbstractCodeGenerator
 	instanceVariableNames: 'currentClass source'
 	package: 'Compiler-Core'!
@@ -8,16 +8,16 @@ I am the abstract super class of all code generators and provide their common AP
 !AbstractCodeGenerator methodsFor: 'accessing'!
 
 classNameFor: aClass
-	^aClass isMetaclass
-		ifTrue: [aClass instanceClass name, '.klass']
+	^ aClass isMetaclass
+		ifTrue: [ aClass instanceClass name, '.klass' ]
 		ifFalse: [
 		aClass isNil
-			ifTrue: ['nil']
-			ifFalse: [aClass name]]
+			ifTrue: [ 'nil' ]
+			ifFalse: [ aClass name ]]
 !
 
 currentClass
-	^currentClass
+	^ currentClass
 !
 
 currentClass: aClass
@@ -25,17 +25,11 @@ currentClass: aClass
 !
 
 pseudoVariables
-	^ Smalltalk current pseudoVariableNames
-!
-
-safeVariableNameFor: aString
-	^(Smalltalk current reservedWords includes: aString)
-		ifTrue: [aString, '_']
-		ifFalse: [aString]
+	^ Smalltalk pseudoVariableNames
 !
 
 source
-	^source ifNil: ['']
+	^ source ifNil: [ '' ]
 !
 
 source: aString
@@ -94,7 +88,7 @@ The default code generator is an instance of `InlinedCodeGenerator`!
 !Compiler methodsFor: 'accessing'!
 
 codeGeneratorClass
-	^codeGeneratorClass ifNil: [InliningCodeGenerator]
+	^ codeGeneratorClass ifNil: [ InliningCodeGenerator ]
 !
 
 codeGeneratorClass: aClass
@@ -102,7 +96,7 @@ codeGeneratorClass: aClass
 !
 
 currentClass
-	^currentClass
+	^ currentClass
 !
 
 currentClass: aClass
@@ -110,7 +104,7 @@ currentClass: aClass
 !
 
 source
-	^source ifNil: ['']
+	^ source ifNil: [ '' ]
 !
 
 source: aString
@@ -118,7 +112,7 @@ source: aString
 !
 
 unknownVariables
-	^unknownVariables
+	^ unknownVariables
 !
 
 unknownVariables: aCollection
@@ -128,25 +122,25 @@ unknownVariables: aCollection
 !Compiler methodsFor: 'compiling'!
 
 compile: aString
-	^self compileNode: (self parse: aString)
+	^ self compileNode: (self parse: aString)
 !
 
 compile: aString forClass: aClass
 	self currentClass: aClass.
 	self source: aString.
-	^self compile: aString
+	^ self compile: aString
 !
 
 compileExpression: aString
 	self currentClass: DoIt.
-	self source: 'doIt ^[', aString, '] value'.
-	^self compileNode: (self parse: self source)
+	self source: 'doIt ^ [ ', aString, ' ] value'.
+	^ self compileNode: (self parse: self source)
 !
 
 compileExpression: aString on: anObject
 	self currentClass: anObject class.
-	self source: 'xxxDoIt ^[', aString, '] value'.
-	^self compileNode: (self parse: self source)
+	self source: 'xxxDoIt ^ [ ', aString, ' ] value'.
+	^ self compileNode: (self parse: self source)
 !
 
 compileNode: aNode
@@ -157,7 +151,7 @@ compileNode: aNode
 		currentClass: self currentClass.
 	result := generator compileNode: aNode.
 	self unknownVariables: #().
-	^result
+	^ result
 !
 
 eval: aString
@@ -173,39 +167,42 @@ evaluateExpression: aString on: anObject
 	"Unlike #eval: evaluate a Smalltalk expression with anObject as the receiver and answer the returned object"
 	| result method |
 	method := self eval: (self compileExpression: aString on: anObject).
-	method category: 'xxxDoIt'.
+	method protocol: 'xxxDoIt'.
 	anObject class addCompiledMethod: method.
 	result := anObject xxxDoIt.
 	anObject class removeCompiledMethod: method.
-	^result
+	^ result
 !
 
-install: aString forClass: aBehavior category: anotherString
+install: aString forClass: aBehavior protocol: anotherString
 	^ ClassBuilder new
 		installMethod: (self eval: (self compile: aString forClass: aBehavior))
 		forClass: aBehavior
-		category: anotherString
+		protocol: anotherString
 !
 
 parse: aString
-	^Smalltalk current parse: aString
+	^ Smalltalk parse: aString
 !
 
 parseExpression: aString
-	^self parse: 'doIt ^[', aString, '] value'
+	^ self parse: 'doIt ^ [ ', aString, ' ] value'
 !
 
 recompile: aClass
 	aClass methodDictionary values
-		do: [ :each | self install: each source forClass: aClass category: each category ]
+		do: [ :each | 
+			self 
+				install: each source 
+				forClass: aClass 
+				protocol: each protocol ]
 		displayingProgress: 'Recompiling ', aClass name.
-	"self setupClass: aClass."
 	aClass isMetaclass ifFalse: [ self recompile: aClass class ]
 !
 
 recompileAll
-	Smalltalk current classes 
-		do: [:each | self recompile: each ]
+	Smalltalk classes 
+		do: [ :each | self recompile: each ]
 		displayingProgress: 'Compiling all classes...'
 ! !
 
@@ -216,8 +213,8 @@ recompile: aClass
 !
 
 recompileAll
-	Smalltalk current classes do: [:each |
-		self recompile: each]
+	Smalltalk classes do: [ :each |
+		self recompile: each ]
 ! !
 
 Object subclass: #DoIt
@@ -226,6 +223,11 @@ Object subclass: #DoIt
 !DoIt commentStamp!
 `DoIt` is the class used to compile and evaluate expressions. See `Compiler >> evaluateExpression:`.!
 
+!DoIt methodsFor: 'tests'!
+
+foo ^ Array new add: 3; add: 4; yourself
+! !
+
 Object subclass: #NodeVisitor
 	instanceVariableNames: ''
 	package: 'Compiler-Core'!
@@ -298,3 +300,11 @@ visitVariableNode: aNode
 	^ self visitNode: aNode
 ! !
 
+!String methodsFor: '*Compiler-Core'!
+
+asVariableName
+	^ (Smalltalk reservedWords includes: self)
+		ifTrue: [ self, '_' ]
+		ifFalse: [ self ]
+! !
+

+ 5 - 5
st/Compiler-Exceptions.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Exceptions'!
+Smalltalk createPackage: 'Compiler-Exceptions'!
 Error subclass: #CompilerError
 	instanceVariableNames: ''
 	package: 'Compiler-Exceptions'!
@@ -89,7 +89,7 @@ variableName: aString
 	variableName := aString
 ! !
 
-ErrorHandler subclass: #RethrowErrorHandler
+Object subclass: #RethrowErrorHandler
 	instanceVariableNames: ''
 	package: 'Compiler-Exceptions'!
 !RethrowErrorHandler commentStamp!
@@ -100,11 +100,11 @@ As a result Smalltalk errors are not swallowd by the Amber runtime and compilati
 !RethrowErrorHandler methodsFor: 'error handling'!
 
 basicSignal: anError
-	<throw anError>
+        <throw anError>
 !
 
 handleError: anError
-	super handleError: anError.
-	self basicSignal: anError
+        super handleError: anError.
+        self basicSignal: anError
 ! !
 

+ 91 - 45
st/Compiler-IR.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-IR'!
+Smalltalk createPackage: 'Compiler-IR'!
 NodeVisitor subclass: #IRASTTranslator
 	instanceVariableNames: 'source theClass method sequence nextAlias'
 	package: 'Compiler-IR'!
@@ -87,15 +87,15 @@ aliasTemporally: aCollection
 	
 	aCollection withIndexDo: [ :each :i |
 		each subtreeNeedsAliasing
-			ifTrue: [ threshold := i ]].
+			ifTrue: [ threshold := i ] ].
 
 	result := OrderedCollection new.
 	aCollection withIndexDo: [ :each :i |
 		result add: (i <= threshold
 			ifTrue: [ self alias: each ]
-			ifFalse: [ self visit: each ])].
+			ifFalse: [ self visit: each ]) ].
 
-	^result
+	^ result
 !
 
 visitAssignmentNode: aNode
@@ -113,6 +113,7 @@ visitBlockNode: aNode
 	| closure |
 	closure := IRClosure new
 		arguments: aNode parameters;
+		requiresSmalltalkContext: aNode requiresSmalltalkContext;
 		scope: aNode scope;
 		yourself.
 	aNode scope temps do: [ :each |
@@ -130,19 +131,23 @@ visitBlockSequenceNode: aNode
 		do: [
 			aNode nodes ifNotEmpty: [
 				aNode nodes allButLast do: [ :each |
-					self sequence add: (self visit: each) ].
+					self sequence add: (self visitOrAlias: each) ].
 				aNode nodes last isReturnNode
-					ifFalse: [ self sequence add: (IRBlockReturn new add: (self visit: aNode nodes last); yourself) ]
-					ifTrue: [ self sequence add: (self visit: aNode nodes last) ]]]
+					ifFalse: [ self sequence add: (IRBlockReturn new add: (self visitOrAlias: aNode nodes last); yourself) ]
+					ifTrue: [ self sequence add: (self visitOrAlias: aNode nodes last) ] ]]
 !
 
 visitCascadeNode: aNode
-	| alias |
+	| alias receiver |
 
-	aNode receiver isImmutable ifFalse: [
-		alias := self alias: aNode receiver.
-		aNode nodes do: [ :each |
-			each receiver: (VariableNode new binding: alias variable) ]].
+	aNode receiver isImmutable 
+		ifTrue: [ receiver := aNode receiver ]
+		ifFalse: [
+			alias := self alias: aNode receiver.
+			receiver := VariableNode new binding: alias variable ].
+	
+	aNode nodes do: [ :each |
+			each receiver: receiver ].
 
 	aNode nodes allButLast do: [ :each |
 		self sequence add: (self visit: each) ].
@@ -153,14 +158,14 @@ visitCascadeNode: aNode
 visitDynamicArrayNode: aNode
 	| array |
 	array := IRDynamicArray new.
-	(self aliasTemporally: aNode nodes) do: [:each | array add: each].
+	(self aliasTemporally: aNode nodes) do: [ :each | array add: each ].
 	^ array
 !
 
 visitDynamicDictionaryNode: aNode
 	| dictionary |
 	dictionary := IRDynamicDictionary new.
-	(self aliasTemporally: aNode nodes) do: [:each | dictionary add: each].
+	(self aliasTemporally: aNode nodes) do: [ :each | dictionary add: each ].
 	^ dictionary
 !
 
@@ -177,8 +182,9 @@ visitMethodNode: aNode
 		theClass: self theClass;
 		arguments: aNode arguments;
 		selector: aNode selector;
-		messageSends: aNode messageSends;
+		sendIndexes: aNode sendIndexes;
 		superSends: aNode superSends;
+		requiresSmalltalkContext: aNode requiresSmalltalkContext;
 		classReferences: aNode classReferences;
 		scope: aNode scope;
 		yourself).
@@ -199,6 +205,12 @@ visitMethodNode: aNode
 	^ self method
 !
 
+visitOrAlias: aNode
+	^ aNode shouldBeAliased
+		ifTrue: [ self alias: aNode ]
+		ifFalse: [ self visit: aNode ]
+!
+
 visitReturnNode: aNode
 	| return |
 	return := aNode nonLocalReturn
@@ -233,9 +245,9 @@ visitSequenceNode: aNode
 		withSequence: IRSequence new
 		do: [
 			aNode nodes do: [ :each | | instruction |
-				instruction := self visit: each.
+				instruction := self visitOrAlias: each.
 				instruction isVariable ifFalse: [
-					self sequence add: instruction ]]]
+					self sequence add: instruction ] ]]
 !
 
 visitValueNode: aNode
@@ -273,6 +285,11 @@ parent
 
 parent: anIRInstruction
 	parent := anIRInstruction
+!
+
+scope
+	^ self parent ifNotNil: [ :node | 
+		node scope ]
 ! !
 
 !IRInstruction methodsFor: 'building'!
@@ -406,7 +423,7 @@ scope: aScope
 ! !
 
 IRScopedInstruction subclass: #IRClosureInstruction
-	instanceVariableNames: 'arguments'
+	instanceVariableNames: 'arguments requiresSmalltalkContext'
 	package: 'Compiler-IR'!
 
 !IRClosureInstruction methodsFor: 'accessing'!
@@ -425,6 +442,14 @@ locals
 		yourself
 !
 
+requiresSmalltalkContext
+	^ requiresSmalltalkContext ifNil: [ false ]
+!
+
+requiresSmalltalkContext: anObject
+	requiresSmalltalkContext := anObject
+!
+
 scope: aScope
 	super scope: aScope.
 	aScope instruction: self
@@ -458,7 +483,7 @@ accept: aVisitor
 ! !
 
 IRClosureInstruction subclass: #IRMethod
-	instanceVariableNames: 'theClass source selector classReferences messageSends superSends internalVariables'
+	instanceVariableNames: 'theClass source selector classReferences sendIndexes superSends requiresSmalltalkContext internalVariables'
 	package: 'Compiler-IR'!
 !IRMethod commentStamp!
 I am a method instruction!
@@ -482,11 +507,7 @@ isMethod
 !
 
 messageSends
-	^ messageSends
-!
-
-messageSends: aCollection
-	messageSends := aCollection
+	^ self sendIndexes keys
 !
 
 method
@@ -501,6 +522,14 @@ selector: aString
 	selector := aString
 !
 
+sendIndexes
+	^ sendIndexes
+!
+
+sendIndexes: aDictionary
+	sendIndexes := aDictionary
+!
+
 source
 	^ source
 !
@@ -537,6 +566,12 @@ IRScopedInstruction subclass: #IRReturn
 !IRReturn commentStamp!
 I am a local return instruction.!
 
+!IRReturn methodsFor: 'accessing'!
+
+scope
+	^ scope ifNil: [ self parent scope ]
+! !
+
 !IRReturn methodsFor: 'testing'!
 
 canBeAssigned
@@ -709,7 +744,7 @@ I am the simplest possible instruction. I represent a value.!
 !IRValue methodsFor: 'accessing'!
 
 value
-	^value
+	^ value
 !
 
 value: aString
@@ -928,10 +963,10 @@ visitIRDynamicArray: anIRDynamicArray
 !
 
 visitIRDynamicDictionary: anIRDynamicDictionary
-	self stream nextPutAll: 'smalltalk.HashedCollection._from_(['.
+	self stream nextPutAll: 'globals.HashedCollection._newFromPairs_(['.
 		anIRDynamicDictionary instructions
 			do: [ :each | self visit: each ]
-			separatedBy: [self stream nextPutAll: ',' ].
+			separatedBy: [ self stream nextPutAll: ',' ].
 	self stream nextPutAll: '])'
 !
 
@@ -951,8 +986,8 @@ visitIRMethod: anIRMethod
 				anIRMethod scope hasNonLocalReturn
 					ifTrue: [
 						self stream nextPutNonLocalReturnHandlingWith: [
-							super visitIRMethod: anIRMethod ]]
-					ifFalse: [ super visitIRMethod: anIRMethod ]]]
+							super visitIRMethod: anIRMethod ] ]
+					ifFalse: [ super visitIRMethod: anIRMethod ] ]]
 			arguments: anIRMethod arguments ]
 !
 
@@ -967,15 +1002,21 @@ visitIRReturn: anIRReturn
 !
 
 visitIRSend: anIRSend
+	| sends |
+	sends := (anIRSend method sendIndexes at: anIRSend selector) size.
+	
 	anIRSend classSend
 		ifNil: [ self visitSend: anIRSend ]
-		ifNotNil: [ self visitSuperSend: anIRSend ]
+		ifNotNil: [ self visitSuperSend: anIRSend ].
+		
+	(sends > 1 and: [ anIRSend index < sends ])
+		ifTrue: [ self stream nextPutSendIndexFor: anIRSend ]
 !
 
 visitIRSequence: anIRSequence
 	self stream nextPutSequenceWith: [
 		anIRSequence instructions do: [ :each |
-			self stream nextPutStatementWith: (self visit: each) ]]
+			self stream nextPutStatementWith: (self visit: each) ] ]
 !
 
 visitIRTempDeclaration: anIRTempDeclaration
@@ -1066,6 +1107,7 @@ nextPutAssignment
 !
 
 nextPutBlockContextFor: anIRClosure during: aBlock
+	anIRClosure requiresSmalltalkContext ifFalse: [ ^ aBlock value ].
 	self
 		nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; lf.
 	
@@ -1080,7 +1122,7 @@ nextPutBlockContextFor: anIRClosure during: aBlock
 			self
 				nextPutAll: each asVariableName;
 				nextPutAll: ':';
-				nextPutAll: each asVariableName]
+				nextPutAll: each asVariableName ]
 		separatedBy: [ self nextPutAll: ',' ].
 	
 	self
@@ -1095,7 +1137,7 @@ nextPutClassRefFunction: aString
 	stream
 		nextPutAll: 'function $';
 		nextPutAll: aString;
-		nextPutAll: '(){return smalltalk.';
+		nextPutAll: '(){return globals.';
 		nextPutAll: aString;
 		nextPutAll: '||(typeof ';
 		nextPutAll: aString;
@@ -1116,6 +1158,8 @@ nextPutClosureWith: aBlock arguments: anArray
 !
 
 nextPutContextFor: aMethod during: aBlock
+	aMethod requiresSmalltalkContext ifFalse: [ ^ aBlock value ].
+	
 	self
 		nextPutAll: 'return smalltalk.withContext(function(', aMethod scope alias, ') { '; lf.
 	aBlock value.
@@ -1129,7 +1173,7 @@ nextPutContextFor: aMethod during: aBlock
 			self
 				nextPutAll: each asVariableName;
 				nextPutAll: ':';
-				nextPutAll: each asVariableName]
+				nextPutAll: each asVariableName ]
 		separatedBy: [ self nextPutAll: ',' ].
 	
 	self
@@ -1179,8 +1223,8 @@ nextPutMethodDeclaration: aMethod with: aBlock
 		nextPutAll: 'args: ', (aMethod arguments collect: [ :each | each value ]) asArray asJavascript, ','; lf;
 		nextPutAll: 'referencedClasses: ['.
 	aMethod classReferences
-		do: [:each | stream nextPutAll: each asJavascript]
-		separatedBy: [stream nextPutAll: ','].
+		do: [ :each | stream nextPutAll: each asJavascript ]
+		separatedBy: [ stream nextPutAll: ',' ].
 	stream
 		nextPutAll: ']';
 		nextPutAll: '})'
@@ -1211,6 +1255,16 @@ nextPutReturnWith: aBlock
 	aBlock value
 !
 
+nextPutSendIndexFor: anIRSend
+	self 
+		nextPutAll: ';'; lf;
+		nextPutAll: anIRSend scope alias;
+		nextPutAll: '.sendIdx[';
+		nextPutAll: anIRSend selector asJavascript;
+		nextPutAll: ']=';
+		nextPutAll: anIRSend index asString
+!
+
 nextPutSequenceWith: aBlock
 	"stream
 		nextPutAll: 'switch(smalltalk.thisContext.pc){'; lf."
@@ -1225,7 +1279,7 @@ nextPutStatementWith: aBlock
 !
 
 nextPutVars: aCollection
-	aCollection ifEmpty: [ ^self ].
+	aCollection ifEmpty: [ ^ self ].
 	
 	stream nextPutAll: 'var '.
 	aCollection
@@ -1240,11 +1294,3 @@ appendToInstruction: anIRInstruction
 	anIRInstruction appendBlock: self
 ! !
 
-!String methodsFor: '*Compiler-IR'!
-
-asVariableName
-	^ (Smalltalk current reservedWords includes: self)
-		ifTrue: [ self, '_' ]
-		ifFalse: [ self ]
-! !
-

+ 1 - 1
st/Compiler-Inlining.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Inlining'!
+Smalltalk createPackage: 'Compiler-Inlining'!
 IRAssignment subclass: #IRInlinedAssignment
 	instanceVariableNames: ''
 	package: 'Compiler-Inlining'!

+ 94 - 127
st/Compiler-Interpreter.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Interpreter'!
+Smalltalk createPackage: 'Compiler-Interpreter'!
 BlockClosure subclass: #AIBlockClosure
 	instanceVariableNames: 'node outerContext'
 	package: 'Compiler-Interpreter'!
@@ -95,7 +95,7 @@ forContext: aContext node: aNode
 ! !
 
 MethodContext subclass: #AIContext
-	instanceVariableNames: 'outerContext innerContext pc locals selector index ast interpreter'
+	instanceVariableNames: 'outerContext innerContext pc locals selector index sendIndexes evaluatedSelector ast interpreter'
 	package: 'Compiler-Interpreter'!
 !AIContext commentStamp!
 I am like a `MethodContext`, used by the `ASTInterpreter`.
@@ -105,6 +105,14 @@ When debugging, my instances are created by copying the current `MethodContext`
 
 !AIContext methodsFor: 'accessing'!
 
+evaluatedSelector
+	^ evaluatedSelector
+!
+
+evaluatedSelector: aString
+	evaluatedSelector := aString
+!
+
 index
 	^ index ifNil: [ 0 ]
 !
@@ -135,7 +143,7 @@ localAt: aString ifAbsent: aBlock
 	^ self locals at: aString ifAbsent: [ 
 		self outerContext 
 			ifNotNil: [ :context | context localAt: aString ifAbsent: aBlock ]
-			ifNil: [aBlock value] ]
+			ifNil: [ aBlock value ] ]
 !
 
 localAt: aString put: anObject
@@ -159,7 +167,8 @@ outerContext
 
 outerContext: anAIContext
 	outerContext := anAIContext.
-	outerContext innerContext: self
+	outerContext ifNotNil: [ :context | 
+		context innerContext: self ]
 !
 
 selector
@@ -168,6 +177,28 @@ selector
 
 selector: aString
 	selector := aString
+!
+
+sendIndexAt: aString
+	^ self sendIndexes at: aString ifAbsent: [ 0 ]
+!
+
+sendIndexes
+	^ sendIndexes ifNil: [ Dictionary new ]
+!
+
+sendIndexes: aDictionary
+	sendIndexes := aDictionary
+! !
+
+!AIContext methodsFor: 'evaluating'!
+
+evaluateNode: aNode
+	^ ASTInterpreter new
+		context: self;
+		node: aNode nextChild;
+		proceed;
+		result
 ! !
 
 !AIContext methodsFor: 'factory'!
@@ -188,9 +219,10 @@ initializeAST
 
 initializeFromMethodContext: aMethodContext
 
-	self 
-		pc: aMethodContext pc;
+	self
+		evaluatedSelector: aMethodContext evaluatedSelector;
 		index: aMethodContext index;
+		sendIndexes: aMethodContext sendIndexes;
 		receiver: aMethodContext receiver;
 		selector: aMethodContext selector.
 		
@@ -205,12 +237,10 @@ initializeFromMethodContext: aMethodContext
 initializeInterpreter
 	interpreter := ASTInterpreter new
 		context: self;
-		node: self retrieveNode;
 		yourself.
 	
-	(self innerContext notNil and: [ 
-		self innerContext isBlockContext not ]) ifTrue: [
-			self setupInterpreter: interpreter ]
+	self innerContext ifNotNil: [
+		self setupInterpreter: interpreter ]
 !
 
 initializeLocals
@@ -242,14 +272,6 @@ interpreter: anInterpreter
 	interpreter := anInterpreter
 !
 
-pc
-	^ pc ifNil: [ pc := 0 ]
-!
-
-pc: anInteger
-	pc := anInteger
-!
-
 receiver
 	^ self localAt: 'self'
 !
@@ -258,17 +280,19 @@ receiver: anObject
 	self localAt: 'self' put: anObject
 !
 
-retrieveNode
-	^ self ast ifNotNil: [
-		ASTPCNodeVisitor new
+setupInterpreter: anInterpreter
+	| currentNode |
+	
+	"Retrieve the current node"
+	currentNode := ASTPCNodeVisitor new
+			selector: self evaluatedSelector;
 			context: self;
 			visit: self ast;
-			currentNode ]
-!
-
-setupInterpreter: anInterpreter
-	"Push the send args and receiver to the interpreter stack"
+			currentNode.
 	
+	anInterpreter node: currentNode.
+
+	"Push the send args and receiver to the interpreter stack"	
 	self innerContext arguments reversed do: [ :each | 
 		anInterpreter push: each ].
 		
@@ -288,9 +312,9 @@ Object subclass: #ASTDebugger
 	package: 'Compiler-Interpreter'!
 !ASTDebugger commentStamp!
 I am a stepping debugger interface for Amber code.
-I internally use an instance of `ASTSteppingInterpreter` to actually step through node and interpret them.
+I internally use an instance of `ASTInterpreter` to actually step through node and interpret them.
 
-My instances are created from a `MethodContext` with `ASTDebugger class >> context:`.
+My instances are created from an `AIContext` with `ASTDebugger class >> context:`.
 They hold an `AIContext` instance internally, recursive copy of the `MethodContext`.
 
 ## API
@@ -308,11 +332,7 @@ context: aContext
 !
 
 interpreter
-	^ interpreter ifNil: [ interpreter := self defaultInterpreterClass new ]
-!
-
-interpreter: anInterpreter
-	interpreter := anInterpreter
+	^ self context interpreter
 !
 
 method
@@ -323,45 +343,6 @@ nextNode
 	^ self interpreter nextNode
 ! !
 
-!ASTDebugger methodsFor: 'defaults'!
-
-defaultInterpreterClass
-	^ ASTInterpreter
-! !
-
-!ASTDebugger methodsFor: 'initialization'!
-
-buildAST
-	"Build the AST tree from the method source code.
-	The AST is annotated with a SemanticAnalyzer,
-	to know the semantics and bindings of each node needed for later debugging"
-	
-	| ast |
-	
-	ast := Smalltalk current parse: self method source.
-	(SemanticAnalyzer on: self context receiver class)
-		visit: ast.
-	
-	^ ast
-!
-
-initializeInterpreter
-	| ast next |
-	ast := self buildAST.
-	next := ASTPCNodeVisitor new
-		context: self context;
-		visit: ast;
-		currentNode.
-	self interpreter node: next
-!
-
-initializeWithContext: aContext
-	"TODO: do we need to handle block contexts?"
-	
-	self context: aContext.
-	self initializeInterpreter
-! !
-
 !ASTDebugger methodsFor: 'stepping'!
 
 proceed
@@ -372,11 +353,16 @@ restart
 	self interpreter restart
 !
 
+skip
+	self interpreter skip
+!
+
 stepInto
 	self shouldBeImplemented
 !
 
 stepOver
+	self flushOuterContexts.
 	self interpreter stepOver
 ! !
 
@@ -390,7 +376,7 @@ atEnd
 
 context: aContext
 	^ self new
-		initializeWithContext: aContext;
+		context: aContext;
 		yourself
 ! !
 
@@ -469,8 +455,8 @@ next
 proceed
 	"Eagerly evaluate the ast"
 	
-	[ self atEnd ] whileFalse: [ 
-		self step ]
+	[ self atEnd ] 
+		whileFalse: [ self step ]
 !
 
 restart
@@ -633,18 +619,14 @@ visitDynamicArrayNode: aNode
 !
 
 visitDynamicDictionaryNode: aNode
-	| associations hashedCollection |
+	| keyValueList |
 	
-	associations := OrderedCollection new.
-	hashedCollection := HashedCollection new.
+	keyValueList := OrderedCollection new.
 	
 	aNode nodes do: [ :each | 
-		associations add: self pop ].
+		keyValueList add: self pop ].
 	
-	associations reversed do: [ :each |
-		hashedCollection add: each ].
-	
-	self push: hashedCollection
+	self push: (HashedCollection newFromPairs: keyValueList reversed)
 !
 
 visitJSStatementNode: aNode
@@ -673,8 +655,6 @@ visitSendNode: aNode
 	
 	result := self sendMessage: message to: receiver superSend: aNode superSend.
 	
-	self context pc: self context pc + 1.
-	
 	"For cascade sends, push the reciever if the send is not the last one"
 	(aNode isCascadeSendNode and: [ aNode isLastChild not ])
 		ifTrue: [ self push: receiver ]
@@ -696,9 +676,9 @@ visitVariableNode: aNode
 			ifAbsent: [
 				aNode value isCapitalized
 					ifTrue: [
-						Smalltalk current 
+						Smalltalk globals 
 							at: aNode value 
-							ifAbsent: [ PlatformInterface globals at: aNode value ]]]])
+							ifAbsent: [ PlatformInterface globals at: aNode value ] ] ] ])
 ! !
 
 Error subclass: #ASTInterpreterError
@@ -708,23 +688,19 @@ Error subclass: #ASTInterpreterError
 I get signaled when an AST interpreter is unable to interpret a node.!
 
 NodeVisitor subclass: #ASTPCNodeVisitor
-	instanceVariableNames: 'useInlinings pc context blockIndex currentNode'
+	instanceVariableNames: 'context index selector currentNode'
 	package: 'Compiler-Interpreter'!
 !ASTPCNodeVisitor commentStamp!
-I visit an AST until I get to the current pc node and answer it.
+I visit an AST until I get to the current node for the `context` and answer it.
 
 ## API
 
 My instances must be filled with a context object using `#context:`.
 
-After visiting the AST the current node corresponding to the `pc` is answered by `#currentNode`!
+After visiting the AST the current node is answered by `#currentNode`!
 
 !ASTPCNodeVisitor methodsFor: 'accessing'!
 
-blockIndex
-	^ blockIndex ifNil: [ blockIndex := 0 ]
-!
-
 context
 	^ context
 !
@@ -737,56 +713,41 @@ currentNode
 	^ currentNode
 !
 
-increaseBlockIndex
-	blockIndex := self blockIndex + 1
+increaseIndex
+	index := self index + 1
 !
 
-pc
-	^ pc ifNil: [ 0 ]
-!
-
-pc: anInteger
-	pc := anInteger
+index
+	^ index ifNil: [ index := 0 ]
 !
 
-useInlinings
-	^ useInlinings ifNil: [ true ]
+selector
+	^ selector
 !
 
-useInlinings: aBoolean
-	useInlinings := aBoolean
+selector: aString
+	selector := aString
 ! !
 
 !ASTPCNodeVisitor methodsFor: 'visiting'!
 
-visitBlockNode: aNode
-	"Inlined send node. Assume that the block is inlined"
-	(aNode parent isSendNode and: [ aNode parent shouldBeInlined ])
-		ifFalse: [
-			self blockIndex >= self context index ifFalse: [
-				self increaseBlockIndex.
-				super visitBlockNode: aNode ] ]
-		ifTrue: [ super visitBlockNode: aNode ]
-!
-
 visitJSStatementNode: aNode
+	"If a JSStatementNode is encountered, it always is the current node.
+	Stop visiting the AST there"
+	
 	currentNode := aNode
 !
 
 visitSendNode: aNode
+	| sendIndex |
+	sendIndex := self context sendIndexAt: self selector.
+	
 	super visitSendNode: aNode.
 	
-	self pc = self context pc ifFalse: [
-		aNode shouldBeInlined ifFalse: [
-			self blockIndex = self context index ifTrue: [
-				self pc: self pc + 1.
-				currentNode := aNode ] ] ]
-! !
-
-!Node methodsFor: '*Compiler-Interpreter'!
-
-isSteppingNode
-	^ false
+	self selector = aNode selector ifTrue: [
+		self index < sendIndex ifFalse: [ 
+			self index > sendIndex ifFalse: [ currentNode := aNode ] ].
+		self increaseIndex ]
 ! !
 
 !AssignmentNode methodsFor: '*Compiler-Interpreter'!
@@ -819,6 +780,12 @@ isSteppingNode
 	^ true
 ! !
 
+!Node methodsFor: '*Compiler-Interpreter'!
+
+isSteppingNode
+	^ false
+! !
+
 !SendNode methodsFor: '*Compiler-Interpreter'!
 
 isSteppingNode

+ 23 - 6
st/Compiler-Semantic.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Semantic'!
+Smalltalk createPackage: 'Compiler-Semantic'!
 Object subclass: #LexicalScope
 	instanceVariableNames: 'node instruction temps args outerScope blockIndex'
 	package: 'Compiler-Semantic'!
@@ -163,7 +163,7 @@ nonLocalReturns
 pseudoVars
 	pseudoVars ifNil: [
 		pseudoVars := Dictionary new.
-		Smalltalk current pseudoVariableNames do: [ :each |
+		Smalltalk pseudoVariableNames do: [ :each |
 			pseudoVars at: each put: ((PseudoVar on: each)
 				scope: self methodScope;
 				yourself) ]].
@@ -246,6 +246,10 @@ isClassRefVar
 	^ false
 !
 
+isImmutable
+	^ false
+!
+
 isInstanceVar
 	^ false
 !
@@ -303,6 +307,10 @@ I am an argument of a method or block.!
 
 isArgVar
 	^ true
+!
+
+isImmutable
+	^ true
 ! !
 
 ScopeVar subclass: #ClassRefVar
@@ -325,6 +333,10 @@ alias
 
 isClassRefVar
 	^ true
+!
+
+isImmutable
+	^ true
 ! !
 
 ScopeVar subclass: #InstanceVar
@@ -359,6 +371,10 @@ alias
 
 !PseudoVar methodsFor: 'testing'!
 
+isImmutable
+	^ true
+!
+
 isPseudoVar
 	^ true
 ! !
@@ -435,7 +451,7 @@ errorUnknownVariable: aNode
 	| identifier |
 	identifier := aNode value.
 	
-	((Smalltalk current globalJsVariables includes: identifier) not
+	((Smalltalk globalJsVariables includes: identifier) not
 		and: [ self isVariableGloballyUndefined: identifier ])
 			ifTrue: [
 				UnknownVariableError new
@@ -527,7 +543,7 @@ visitMethodNode: aNode
 	aNode scope: currentScope.
 	currentScope node: aNode.
 
-	self theClass allInstanceVariableNames do: [:each |
+	self theClass allInstanceVariableNames do: [ :each |
 		currentScope addIVar: each ].
 	aNode arguments do: [ :each |
 		self validateVariableScope: each.
@@ -537,7 +553,7 @@ visitMethodNode: aNode
 
 	aNode
 		classReferences: self classReferences;
-		messageSends: self messageSends keys;
+		sendIndexes: self messageSends;
 		superSends: self superSends keys.
 	self popScope
 !
@@ -561,7 +577,8 @@ visitSendNode: aNode
 		
 		ifFalse: [ (IRSendInliner inlinedSelectors includes: aNode selector) ifTrue: [
 			aNode shouldBeInlined: true.
-			aNode receiver shouldBeAliased: true ] ].
+			aNode receiver ifNotNil: [ :receiver |
+				receiver shouldBeAliased: true ] ] ].
 
 	self messageSends at: aNode selector ifAbsentPut: [ Set new ].
 	(self messageSends at: aNode selector) add: aNode.

+ 65 - 29
st/Compiler-Tests.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Compiler-Tests'!
+Smalltalk createPackage: 'Compiler-Tests'!
 TestCase subclass: #ASTParsingTest
 	instanceVariableNames: ''
 	package: 'Compiler-Tests'!
@@ -13,7 +13,7 @@ analyze: aNode forClass: aClass
 !ASTParsingTest methodsFor: 'parsing'!
 
 parse: aString
-	^ Smalltalk current parse: aString
+	^ Smalltalk parse: aString
 !
 
 parse: aString forClass: aClass
@@ -27,14 +27,16 @@ ASTParsingTest subclass: #ASTPCNodeVisitorTest
 !ASTPCNodeVisitorTest methodsFor: 'factory'!
 
 astPCNodeVisitor
-	^ self astPCNodeVisitorForPC: 0
+	^ ASTPCNodeVisitor new
+		context: (AIContext new
+			yourself);
+		yourself
 !
 
-astPCNodeVisitorForPC: anInteger
+astPCNodeVisitorForSelector: aString
 	^ ASTPCNodeVisitor new
-		pc: 0;
-		context: (AIContext new 
-			pc: anInteger; 
+		selector: aString;
+		context: (AIContext new
 			yourself);
 		yourself
 ! !
@@ -54,7 +56,16 @@ testMessageSend
 	| ast |
 	
 	ast := self parse: 'foo self asString yourself. ^ self asBoolean' forClass: Object.
-	self assert: ((self astPCNodeVisitorForPC: 2)
+	self assert: ((self astPCNodeVisitorForSelector: 'yourself')
+		visit: ast;
+		currentNode) selector equals: 'yourself'
+!
+
+testMessageSendWithBlocks
+	| ast |
+	
+	ast := self parse: 'foo true ifTrue: [ [ self asString yourself ] value.  ]. ^ self asBoolean' forClass: Object.
+	self assert: ((self astPCNodeVisitorForSelector: 'yourself')
 		visit: ast;
 		currentNode) selector equals: 'yourself'
 !
@@ -63,12 +74,12 @@ testMessageSendWithInlining
 	| ast |
 	
 	ast := self parse: 'foo true ifTrue: [ self asString yourself ]. ^ self asBoolean' forClass: Object.
-	self assert: ((self astPCNodeVisitorForPC: 2)
+	self assert: ((self astPCNodeVisitorForSelector: 'yourself')
 		visit: ast;
 		currentNode) selector equals: 'yourself'.
 		
 	ast := self parse: 'foo true ifTrue: [ self asString yourself ]. ^ self asBoolean' forClass: Object.
-	self assert: ((self astPCNodeVisitorForPC: 3)
+	self assert: ((self astPCNodeVisitorForSelector: 'asBoolean')
 		visit: ast;
 		currentNode) selector equals: 'asBoolean'
 !
@@ -125,7 +136,7 @@ should: aString receiver: anObject return: aResult
 	| method result |
 
 	receiver := anObject.
-	method := self compiler install: aString forClass: anObject class category: 'tests'.
+	method := self compiler install: aString forClass: anObject class protocol: 'tests'.
 	result := receiver perform: method selector.
 	anObject class removeCompiledMethod: method.
 	self assert: aResult equals: result
@@ -164,7 +175,19 @@ testCascades
 	self should: 'foo ^ Array new add: 3; add: 4; yourself' return: #(3 4)
 !
 
+testCascadesWithInlining
+	
+	self should: 'foo ^ true ifTrue: [ 1 ] ifFalse: [ 2 ]' return: 1.
+	self should: 'foo ^ false ifTrue: [ 1 ] ifFalse: [ 2 ]' return: 2
+!
+
 testDynamicArrayElementsOrdered
+	self should: 'foo
+	| x |
+	x := 1.
+	^ { x. x := 2 }
+' return: #(1 2).
+
 	self should: 'foo
 	| x |
 	x := 1.
@@ -175,11 +198,15 @@ testDynamicArrayElementsOrdered
 testDynamicDictionaryElementsOrdered
 	self should: 'foo
 	| x |
-	x := ''foo''->1.
-	^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }
+	x := ''foo''.
+	^ #{ x->1. ''bar''->(true ifTrue: [ 2 ]) }
 ' return: #{'foo'->1. 'bar'->2}.
 !
 
+testDynamicDictionaryWithMoreArrows
+	self should: 'foo ^ #{1->2->3}' return: (HashedCollection with: 1->2->3)
+!
+
 testGlobalVar
 	self should: 'foo ^ eval class' return: BlockClosure.
 	self should: 'foo ^ Math cos: 0' return: 1.
@@ -187,21 +214,30 @@ testGlobalVar
 !
 
 testInnerTemporalDependentElementsOrdered
+	self should: 'foo
+	| x |
+	x := Array.
+	^ x with: ''foo''->x with: ''bar''->(x := 2)
+' return: {'foo'->Array. 'bar'->2}.
+
 	self should: 'foo
 	| x |
 	x := Array.
 	^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])
 ' return: {'foo'->Array. 'bar'->2}.
+
 	self should: 'foo
 	| x |
 	x := 1.
 	^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])
 ' return: {'foo'->1. 'bar'->2}.
+
 	self should: 'foo
 	| x |
 	x := 1.
 	^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }
 ' return: {'foo'->1. 'bar'->2}.
+
 	self should: 'foo
 	| x |
 	x := 1.
@@ -277,7 +313,7 @@ testNonLocalReturn
 !
 
 testPascalCaseGlobal
-	self should: 'foo ^Object' return: (smalltalk at: 'Object').
+	self should: 'foo ^Object' return: (Smalltalk globals at: 'Object').
 	self should: 'foo ^NonExistent' return: nil
 !
 
@@ -405,7 +441,7 @@ analyze: aNode forClass: aClass
 !
 
 parse: aString
-	^ Smalltalk current parse: aString
+	^ Smalltalk parse: aString
 !
 
 parse: aString forClass: aClass
@@ -523,7 +559,7 @@ testAssignment
 	| src ast |
 
 	src := 'foo self := 1'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	self should: [analyzer visit: ast] raise: InvalidAssignmentError
 !
 
@@ -531,7 +567,7 @@ testNonLocalReturn
 	| src ast |
 
 	src := 'foo | a | a + 1. ^ a'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast.
 
 	self deny: ast scope hasNonLocalReturn
@@ -541,7 +577,7 @@ testNonLocalReturn2
 	| src ast |
 
 	src := 'foo | a | a + 1. [ [ ^ a] ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast.
 
 	self assert: ast scope hasNonLocalReturn
@@ -551,7 +587,7 @@ testScope
 	| src ast |
 
 	src := 'foo | a | a + 1. [ | b | b := a ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast.
 
 	self deny: ast nodes first nodes last scope == ast scope.
@@ -561,7 +597,7 @@ testScope2
 	| src ast |
 
 	src := 'foo | a | a + 1. [ [ | b | b := a ] ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast.
 
 	self deny: ast nodes first nodes last nodes first nodes first scope == ast scope.
@@ -571,7 +607,7 @@ testScopeLevel
 	| src ast |
 
 	src := 'foo | a | a + 1. [ [ | b | b := a ] ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast.
 
 	self assert: ast scope scopeLevel equals: 1.
@@ -582,7 +618,7 @@ testUnknownVariables
 	| src ast |
 
 	src := 'foo | a | b + a'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 
 	self should: [ analyzer visit: ast ] raise: UnknownVariableError
 !
@@ -591,7 +627,7 @@ testUnknownVariablesWithScope
 	| src ast |
 
 	src := 'foo | a b | [ c + 1. [ a + 1. d + 1 ]]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	
 	self should: [ analyzer visit: ast ] raise: UnknownVariableError
 !
@@ -599,35 +635,35 @@ testUnknownVariablesWithScope
 testVariableShadowing
 	| src ast |
 	src := 'foo | a | a + 1'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast
 !
 
 testVariableShadowing2
 	| src ast |
 	src := 'foo | a | a + 1. [ | a | a := 2 ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	self should: [analyzer visit: ast] raise: ShadowingVariableError
 !
 
 testVariableShadowing3
 	| src ast |
 	src := 'foo | a | a + 1. [ | b | b := 2 ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast
 !
 
 testVariableShadowing4
 	| src ast |
 	src := 'foo | a | a + 1. [ [ [ | b | b := 2 ] ] ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast
 !
 
 testVariableShadowing5
 	| src ast |
 	src := 'foo | a | a + 1. [ [ [ | a | a := 2 ] ] ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	self should: [analyzer visit: ast] raise: ShadowingVariableError
 !
 
@@ -635,7 +671,7 @@ testVariablesLookup
 	| src ast |
 
 	src := 'foo | a | a + 1. [ | b | b := a ]'.
-	ast := smalltalk parse: src.
+	ast := Smalltalk parse: src.
 	analyzer visit: ast.
 
 	"Binding for `a` in the message send"

+ 9 - 9
st/Examples.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Examples'!
+Smalltalk createPackage: 'Examples'!
 Widget subclass: #Counter
 	instanceVariableNames: 'count header'
 	package: 'Examples'!
@@ -13,12 +13,12 @@ Then take a look in the HTML document above the IDE.
 
 decrease
 	count := count - 1.
-	header contents: [:html | html with: count asString]
+	header contents: [ :html | html with: count asString ]
 !
 
 increase
 	count := count + 1.
-	header contents: [:html | html with: count asString]
+	header contents: [ :html | html with: count asString ]
 ! !
 
 !Counter methodsFor: 'initialization'!
@@ -32,14 +32,14 @@ initialize
 
 renderOn: html
 	header := html h1
-	with: count asString;
-	yourself.
+		with: count asString;
+		yourself.
 	html button
-	with: '++';
-	onClick: [self increase].
+		with: '++';
+		onClick: [ self increase ].
 	html button
-	with: '--';
-	onClick: [self decrease]
+		with: '--';
+		onClick: [ self decrease ]
 ! !
 
 !Counter class methodsFor: 'example'!

+ 15 - 1
st/Helios-Announcements.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Announcements'!
+Smalltalk createPackage: 'Helios-Announcements'!
 Object subclass: #HLAboutToChange
 	instanceVariableNames: 'actionBlock'
 	package: 'Helios-Announcements'!
@@ -286,6 +286,20 @@ HLAnnouncement subclass: #HLShowInstanceToggled
 	instanceVariableNames: ''
 	package: 'Helios-Announcements'!
 
+HLAnnouncement subclass: #HLShowTemplate
+	instanceVariableNames: 'template'
+	package: 'Helios-Announcements'!
+
+!HLShowTemplate methodsFor: 'accessing'!
+
+template
+	^ template
+!
+
+template: aString
+	template := aString
+! !
+
 HLAnnouncement subclass: #HLSourceCodeSaved
 	instanceVariableNames: ''
 	package: 'Helios-Announcements'!

+ 63 - 14
st/Helios-Browser.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Browser'!
+Smalltalk createPackage: 'Helios-Browser'!
 HLWidget subclass: #HLBrowser
 	instanceVariableNames: 'model packagesListWidget classesListWidget protocolsListWidget methodsListWidget sourceWidget bottomDiv'
 	package: 'Helios-Browser'!
@@ -25,6 +25,19 @@ focus
 	^ self packagesListWidget focus
 !
 
+openClassNamed: aString
+	self model openClassNamed: aString
+!
+
+openMethod: aCompiledMethod
+	self model 
+			selectedPackage: aCompiledMethod methodClass package;
+			selectedClass: aCompiledMethod methodClass;
+			selectedProtocol: aCompiledMethod protocol;
+			selectedMethod: aCompiledMethod;
+			focusOnSourceCode
+!
+
 unregister
 	super unregister.
 
@@ -218,7 +231,7 @@ HLToolModel subclass: #HLBrowserModel
 !HLBrowserModel methodsFor: 'accessing'!
 
 showComment
-	^ showComment ifNil: [ false ]
+	^ showComment ifNil: [ true ]
 !
 
 showComment: aBoolean
@@ -238,7 +251,7 @@ showInstance: aBoolean
 
     	self selectedClass ifNotNil: [
     		self selectedClass: (aBoolean
-    			ifTrue: [self selectedClass theNonMetaClass ]
+    			ifTrue: [ self selectedClass theNonMetaClass ]
 	    	  	ifFalse: [ self selectedClass theMetaClass ]) ].
     
 		self announcer announce: HLShowInstanceToggled new ]
@@ -270,6 +283,20 @@ setClassComment: aString
 	self environment
 		setClassCommentOf: self selectedClass theNonMetaClass
 		to: aString
+!
+
+showClassTemplate
+	self selectedPackage ifNotNil: [ :package |
+		self announcer announce: (HLShowTemplate new
+			template: package classTemplate;
+			yourself) ]
+!
+
+showMethodTemplate
+	self selectedClass ifNotNil: [ :theClass |
+		self announcer announce: (HLShowTemplate new
+			template: theClass methodTemplate;
+			yourself) ]
 ! !
 
 !HLBrowserModel methodsFor: 'commands actions'!
@@ -389,8 +416,6 @@ I render a list of classes in the selected package.!
 !HLClassesListWidget methodsFor: 'accessing'!
 
 cssClassForItem: aClass
-	aClass theNonMetaClass comment isEmpty 
-		ifTrue: [ ^ 'uncommented' ].
 	^ aClass theNonMetaClass heliosClass
 !
 
@@ -409,6 +434,13 @@ label
 
 !HLClassesListWidget methodsFor: 'actions'!
 
+focus
+	super focus.
+	
+	self selectedItem 
+		ifNil: [ self model showClassTemplate ]
+!
+
 focusMethodsListWidget
 	self model announcer announce: HLMethodsListFocus new
 !
@@ -488,9 +520,9 @@ toggleShowComment
 setItemsForPackage: aPackage
 	self items: (aPackage 
     	ifNil: [ #() ]
-  		ifNotNil: [ ((aPackage classes 
-        	collect: [ :each | each theNonMetaClass ]) asSet asArray) 
-            	sort: [:a :b | a name < b name ] ]).
+  		ifNotNil: [ (aPackage classes 
+        	collect: [ :each | each theNonMetaClass ]) 
+            	sort: [ :a :b | a name < b name ] ]).
 !
 
 setItemsForSelectedPackage
@@ -560,6 +592,7 @@ onClassRemoved: anAnnouncement
 
 	class package = self model selectedPackage ifFalse: [ ^ self ].
     
+	self selectItem: nil.
     self setItemsForSelectedPackage.
     self refresh
 !
@@ -642,10 +675,8 @@ renderItem: aClass level: anInteger on: html
 	| li |
     
 	li := html li.
-	self registerMappingFrom: aClass to: li.
-	
+	li asJQuery data: 'item' put: aClass.
     li
-    	at: 'list-data' put: (self items indexOf: aClass);
 		class: (self listCssClassForItem: aClass);
 		with: [ 
         	html a
@@ -668,7 +699,7 @@ renderItem: aClass on: html
 renderItemLabel: aClass level: anInteger on: html
 	html span asJQuery html: (String streamContents: [ :str |
 		anInteger timesRepeat: [
-			str nextPutAll: '&nbsp;&nbsp;&nbsp;&nbsp;'].
+			str nextPutAll: '&nbsp;&nbsp;&nbsp;&nbsp;' ].
 			str nextPutAll: aClass name ])
 !
 
@@ -766,8 +797,7 @@ unregister
 !HLDocumentationWidget methodsFor: 'defaults'!
 
 defaultDocumentation
-	^ 'No documentation available. 
-**That''s bad. Seriously.**'
+	^ 'No documentation is available for this class.'
 !
 
 defaultHead
@@ -914,6 +944,13 @@ selectorsInProtocol: aString
 
 !HLMethodsListWidget methodsFor: 'actions'!
 
+focus
+	super focus.
+	
+	self selectedItem ifNil: [
+		self model showMethodTemplate ]
+!
+
 observeModel
 	self model announcer 
 		on: HLProtocolSelected 
@@ -1133,10 +1170,16 @@ observeSystem
     self model systemAnnouncer 
 		on: ClassAdded 
 		send: #onClassAdded:
+		to: self.
+		
+	self model systemAnnouncer
+		on: PackageAdded
+		send: #onPackageAdded:
 		to: self
 !
 
 selectItem: aPackage
+	super selectItem: aPackage.
 	self model selectedPackage: aPackage
 ! !
 
@@ -1158,6 +1201,12 @@ onClassAdded: anAnnouncement
 			refresh ]
 !
 
+onPackageAdded: anAnnouncement
+	self 
+		initializeItems;
+		refresh
+!
+
 onPackageSelected: anAnnouncement
 	| package |
 	

+ 111 - 1
st/Helios-Commands-Browser.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Commands-Browser'!
+Smalltalk createPackage: 'Helios-Commands-Browser'!
 HLToolCommand subclass: #HLBrowserCommand
 	instanceVariableNames: ''
 	package: 'Helios-Commands-Browser'!
@@ -155,6 +155,116 @@ label
 	^ 'Edit documentation'
 ! !
 
+HLBrowserCommand subclass: #HLGenerateCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Browser'!
+!HLGenerateCommand commentStamp!
+I am a group command used to gather all the commands generating code (`accessors`, `initialize`, etc)!
+
+!HLGenerateCommand class methodsFor: 'accessing'!
+
+key
+	^ 'h'
+!
+
+label
+	^ 'Generate'
+! !
+
+HLGenerateCommand subclass: #HLCategorizeUnclassifiedCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Browser'!
+!HLCategorizeUnclassifiedCommand commentStamp!
+I am the command used to categorize unclassified methods!
+
+!HLCategorizeUnclassifiedCommand methodsFor: 'executing'!
+
+execute
+	| targetClass unclassified |
+	targetClass := self model selectedClass.
+
+	unclassified := targetClass methods select:[ :e | e protocol = 'as yet unclassified' ].
+		
+	HLMethodClassifier new
+		classifyAll: unclassified
+! !
+
+!HLCategorizeUnclassifiedCommand class methodsFor: 'accessing'!
+
+key
+	^ 'c'
+!
+
+label
+	^ 'Categorize'
+! !
+
+HLGenerateCommand subclass: #HLGenerateAccessorsCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Browser'!
+!HLGenerateAccessorsCommand commentStamp!
+I am the command used to generate the `getter` and the `setter` methods depending of the selected class!
+
+!HLGenerateAccessorsCommand methodsFor: 'executing'!
+
+execute
+	| targetClass output first |
+	targetClass := self model selectedClass.
+
+	output := HLInitializeGenerator new
+		class: targetClass;
+		generate;
+		output.
+		
+	output compile.
+	first := output sourceCodes first.
+	self model
+		selectedProtocol: output protocol;
+		selectedMethod:(targetClass>>first selector);
+		focusOnSourceCode
+! !
+
+!HLGenerateAccessorsCommand class methodsFor: 'accessing'!
+
+key
+	^ 'i'
+!
+
+label
+	^ 'Initialize'
+! !
+
+HLGenerateCommand subclass: #HLGenerateInitializeCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Browser'!
+!HLGenerateInitializeCommand commentStamp!
+I am the command used to generate the `initialize` method depending of the selected class!
+
+!HLGenerateInitializeCommand methodsFor: 'executing'!
+
+execute
+	| targetClass output |
+	targetClass := self model selectedClass.
+
+	output := HLAccessorsGenerator new
+		class: targetClass;
+		generate;
+		output.
+		
+	output compile.
+	self model selectedProtocol: output protocol
+! !
+
+!HLGenerateInitializeCommand class methodsFor: 'accessing'!
+
+key
+	^ 'a'
+!
+
+label
+	^ 'Accessors'
+! !
+
 HLBrowserCommand subclass: #HLToggleCommand
 	instanceVariableNames: ''
 	package: 'Helios-Commands-Browser'!

+ 2 - 2
st/Helios-Commands-Core.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Commands-Core'!
+Smalltalk createPackage: 'Helios-Commands-Core'!
 Object subclass: #HLCommand
 	instanceVariableNames: 'input'
 	package: 'Helios-Commands-Core'!
@@ -310,7 +310,7 @@ key
 !
 
 label
-	^ 'Switch'
+	^ 'Switch tab'
 ! !
 
 HLCommand subclass: #HLViewCommand

+ 50 - 18
st/Helios-Commands-Tools.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Commands-Tools'!
+Smalltalk createPackage: 'Helios-Commands-Tools'!
 HLModelCommand subclass: #HLToolCommand
 	instanceVariableNames: ''
 	package: 'Helios-Commands-Tools'!
@@ -23,6 +23,38 @@ isValidFor: aModel
 	^ aModel isToolModel
 ! !
 
+HLToolCommand subclass: #HLBrowseMethodCommand
+	instanceVariableNames: ''
+	package: 'Helios-Commands-Tools'!
+
+!HLBrowseMethodCommand methodsFor: 'accessing'!
+
+displayLabel
+	^ 'browse method'
+! !
+
+!HLBrowseMethodCommand methodsFor: 'executing'!
+
+execute
+	self model openMethod
+! !
+
+!HLBrowseMethodCommand class methodsFor: 'accessing'!
+
+key
+	^ 'b'
+!
+
+label
+	^ 'browse method'
+! !
+
+!HLBrowseMethodCommand class methodsFor: 'testing'!
+
+isValidFor: aModel
+	^ aModel isReferencesModel
+! !
+
 HLToolCommand subclass: #HLCommitPackageCommand
 	instanceVariableNames: ''
 	package: 'Helios-Commands-Tools'!
@@ -53,7 +85,7 @@ key
 !
 
 label
-	^ 'Commit'
+	^ 'Commit package'
 ! !
 
 HLToolCommand subclass: #HLCopyCommand
@@ -113,7 +145,7 @@ key
 !
 
 label
-	^ 'Class'
+	^ 'Copy class'
 !
 
 menuLabel
@@ -171,13 +203,13 @@ key
 !
 
 label
-	^ 'Class'
+	^ 'Find class'
 ! !
 
 !HLFindClassCommand class methodsFor: 'testing'!
 
 isValidFor: aModel
-	^ aModel isBrowserModel
+	^ true
 ! !
 
 HLFindCommand subclass: #HLFindReferencesCommand
@@ -205,7 +237,7 @@ defaultInput
 		ifNil: [
 			self model selectedClass
 				ifNil: [ '' ]
-				ifNotNil: [ :class | class name ] ]
+				ifNotNil: [ :class | class theNonMetaClass name ] ]
 		ifNotNil: [ :method | method selector ]
 ! !
 
@@ -230,7 +262,7 @@ key
 !
 
 label
-	^ 'References'
+	^ 'Find references'
 ! !
 
 HLToolCommand subclass: #HLMoveToCommand
@@ -264,7 +296,7 @@ key
 !
 
 label
-	^ 'Class'
+	^ 'Move class'
 ! !
 
 HLMoveClassToCommand subclass: #HLMoveClassToPackageCommand
@@ -308,7 +340,7 @@ key
 !
 
 label
-	^ 'to package'
+	^ 'Move class to package'
 !
 
 menuLabel	
@@ -338,7 +370,7 @@ key
 !
 
 label
-	^ 'Method'
+	^ 'Move method'
 ! !
 
 HLMoveMethodToCommand subclass: #HLMoveMethodToClassCommand
@@ -378,7 +410,7 @@ key
 !
 
 label	
-	^ 'to class'
+	^ 'Move method to class'
 !
 
 menuLabel	
@@ -422,7 +454,7 @@ key
 !
 
 label
-	^ 'to protocol'
+	^ 'Move method to protocol'
 !
 
 menuLabel
@@ -472,7 +504,7 @@ key
 !
 
 label
-	^ 'Class'
+	^ 'Remove class'
 !
 
 menuLabel
@@ -508,7 +540,7 @@ key
 !
 
 label
-	^ 'Method'
+	^ 'Remove method'
 !
 
 menuLabel
@@ -544,7 +576,7 @@ key
 !
 
 label
-	^ 'Protocol'
+	^ 'Remove protocol'
 !
 
 menuLabel
@@ -582,7 +614,7 @@ displayLabel
 !HLRenameClassCommand methodsFor: 'defaults'!
 
 defaultInput
-	^ self model selectedClass name
+	^ self model selectedClass theNonMetaClass name
 ! !
 
 !HLRenameClassCommand methodsFor: 'executing'!
@@ -608,7 +640,7 @@ key
 !
 
 label
-	^ 'Class'
+	^ 'Rename class'
 !
 
 menuLabel
@@ -658,7 +690,7 @@ key
 !
 
 label
-	^ 'Protocol'
+	^ 'Rename protocol'
 !
 
 menuLabel

+ 96 - 71
st/Helios-Core.st

@@ -1,5 +1,5 @@
-Smalltalk current createPackage: 'Helios-Core'!
-Object subclass: #HLModel
+Smalltalk createPackage: 'Helios-Core'!
+InterfacingObject subclass: #HLModel
 	instanceVariableNames: 'announcer environment'
 	package: 'Helios-Core'!
 !HLModel commentStamp!
@@ -92,6 +92,16 @@ availableProtocols
 	^ self environment availableProtocolsFor: self selectedClass
 !
 
+packageToCommit
+	"Answer the package to commit depending on the context:
+	- if a Method is selected, answer its package
+	- else answer the `selectedPackage`"
+	
+	^ self selectedMethod 
+		ifNil: [ self selectedPackage ]
+		ifNotNil: [ :method | method package ]
+!
+
 packages
 	^ self environment packages
 !
@@ -191,9 +201,7 @@ saveSourceCode
 !HLToolModel methodsFor: 'commands actions'!
 
 commitPackage
-	"self 
-		withHelperLabelled: 'Committing package ', self selectedPackage name, '...'
-		do: [ "self environment commitPackage: self selectedPackage" ]"
+	self environment commitPackage: self packageToCommit
 !
 
 copyClassTo: aClassName
@@ -348,7 +356,7 @@ withCompileErrorHandling: aBlock
 				self environment 
 					evaluate: aBlock
 					on: ParseError
-					do: [:ex | self handleParseError: ex ] ]
+					do: [ :ex | self handleParseError: ex ] ]
 			on: UnknownVariableError
 			do: [ :ex | self handleUnkownVariableError: ex ] ]
 		on: CompilerError
@@ -394,7 +402,7 @@ isToolModel
 
 shouldCompileClassDefinition: aString
 	^ self selectedClass isNil or: [
-		aString match: '^[A-Z]' ]
+		aString match: '^\s*[A-Z]' ]
 ! !
 
 !HLToolModel class methodsFor: 'actions'!
@@ -406,7 +414,7 @@ on: anEnvironment
         yourself
 ! !
 
-ProgressHandler subclass: #HLProgressHandler
+Object subclass: #HLProgressHandler
 	instanceVariableNames: ''
 	package: 'Helios-Core'!
 !HLProgressHandler commentStamp!
@@ -659,7 +667,13 @@ refresh
 !HLWidget class methodsFor: 'accessing'!
 
 openAsTab
-	HLManager current addTab: (HLTabWidget on: self new labelled: self tabLabel)
+	| instance |
+	
+	instance := self new.
+	HLManager current addTab: (HLTabWidget 
+		on: instance 
+		labelled: self tabLabel).
+	^ instance
 !
 
 tabClass
@@ -737,7 +751,7 @@ hasFocus
 ! !
 
 HLFocusableWidget subclass: #HLListWidget
-	instanceVariableNames: 'items selectedItem mapping'
+	instanceVariableNames: 'items selectedItem'
 	package: 'Helios-Core'!
 
 !HLListWidget methodsFor: 'accessing'!
@@ -746,6 +760,11 @@ cssClassForItem: anObject
 	^ ''
 !
 
+findListItemFor: anObject
+	^ (((wrapper asJQuery find: 'li') 
+		filter: [ :thisArg :otherArg | (thisArg asJQuery data: 'item') = anObject ] currySelf) eq: 0)
+!
+
 items
 	^ items ifNil: [ items := self defaultItems ]
 !
@@ -781,22 +800,20 @@ activateFirstListItem
 !
 
 activateItem: anObject
-	self activateListItem: (mapping 
-		at: anObject
-		ifAbsent: [ ^ self ]) asJQuery
+	self activateListItem: (self findListItemFor: anObject)
 !
 
 activateListItem: aListItem
 	| item |
 	
-	(aListItem get: 0) ifNil: [ ^self ].
+	(aListItem get: 0) ifNil: [ ^ self ].
 	aListItem parent children removeClass: 'active'.
 	aListItem addClass: 'active'.
     
 	self ensureVisible: aListItem.
     
    "Activate the corresponding item"
-   item := (self items at: (aListItem attr: 'list-data') asNumber).
+   item := aListItem data: 'item'.
    self selectedItem == item ifFalse: [
 	   self selectItem: item ]
 !
@@ -817,7 +834,7 @@ ensureVisible: aListItem
 	"Move the scrollbar to show the active element"
 	
 	| parent position |
-	
+	(aListItem get: 0) ifNil: [ ^ self ].
 	position := self positionOf: aListItem.
 	parent := aListItem parent.
 	
@@ -835,10 +852,7 @@ focus
 
 refresh
 	super refresh.
-	
-	self ensureVisible: (mapping 
-		at: self selectedItem
-		ifAbsent: [ ^ self ]) asJQuery
+	self selectedItem ifNotNil: [self ensureVisible: (self findListItemFor: self selectedItem)].
 !
 
 selectItem: anObject
@@ -860,20 +874,6 @@ setupKeyBindings
 		rebindKeys
 ! !
 
-!HLListWidget methodsFor: 'initialization'!
-
-initialize
-	super initialize.
-	
-	mapping := Dictionary new.
-! !
-
-!HLListWidget methodsFor: 'private'!
-
-registerMappingFrom: anObject to: aTag
-	mapping at: anObject put: aTag
-! !
-
 !HLListWidget methodsFor: 'rendering'!
 
 renderButtonsOn: html
@@ -893,10 +893,8 @@ renderItem: anObject on: html
 	| li |
     
 	li := html li.
-	self registerMappingFrom: anObject to: li.
-	
+	li asJQuery data: 'item' put: anObject.
     li
-        at: 'list-data' put: (self items indexOf: anObject) asString;
 		class: (self listCssClassForItem: anObject);
         with: [ 
         	html a
@@ -912,10 +910,8 @@ renderItemLabel: anObject on: html
 !
 
 renderListOn: html
-	mapping := Dictionary new.
-	
-	self items do: [ :each | 
-    	self renderItem: each on: html ]
+	self items do: [ :each  | 
+    	self renderItem: each  on: html ]
 ! !
 
 HLListWidget subclass: #HLNavigationListWidget
@@ -1195,18 +1191,6 @@ confirm: aString ifTrue: aBlock
 		show
 !
 
-registerErrorHandler: anErrorHandler
-	self environment registerErrorHandler: anErrorHandler
-!
-
-registerInspector: anInspector
-	self environment registerInspector: anInspector
-!
-
-registerProgressHandler: aProgressHandler
-	self environment registerProgressHandler: aProgressHandler
-!
-
 removeActiveTab
 	self removeTab: self activeTab
 !
@@ -1247,29 +1231,34 @@ request: aString value: valueString do: aBlock
 defaultEnvironment
 	"If helios is loaded from within a frame, answer the parent window environment"
 	
-	| parent parentSmalltalk |
+	| parent parentSmalltalkGlobals |
 	
 	parent := window opener ifNil: [ window parent ].
 	parent ifNil: [ ^ Environment new ].
 	
-	parentSmalltalk := (parent at: 'requirejs') value: 'amber_vm/smalltalk'.
-	parentSmalltalk ifNil: [ ^ Environment new ].
+	parentSmalltalkGlobals := (parent at: 'requirejs') value: 'amber_vm/globals'.
+	parentSmalltalkGlobals ifNil: [ ^ Environment new ].
 	
-	^ (parentSmalltalk at: 'Environment') new
+	^ (parentSmalltalkGlobals at: 'Environment') new
 ! !
 
 !HLManager methodsFor: 'initialization'!
 
-initialize
-	super initialize.
-	
-	HLErrorHandler register.
-	HLProgressHandler register.
-	
-	self registerInspector: HLInspector.
-	self registerErrorHandler: ErrorHandler current.
-	self registerProgressHandler: ProgressHandler current.
-    self keyBinder setupEvents
+setup
+	self registerServices.
+    self keyBinder 
+		setupEvents;
+		setupHelper
+! !
+
+!HLManager methodsFor: 'private'!
+
+registerServices
+	self
+		registerInspector;
+		registerErrorHandler;
+		registerProgressHandler;
+		registerTranscript
 ! !
 
 !HLManager methodsFor: 'rendering'!
@@ -1334,6 +1323,27 @@ show: aTab
 	aTab show; focus
 ! !
 
+!HLManager methodsFor: 'services'!
+
+registerErrorHandler
+	self environment registerErrorHandler: HLErrorHandler new.
+	ErrorHandler register: HLErrorHandler new
+!
+
+registerInspector
+	self environment registerInspector: HLInspector.
+	Inspector register: HLInspector
+!
+
+registerProgressHandler
+	self environment registerProgressHandler: HLProgressHandler new.
+	ProgressHandler register: HLProgressHandler new
+!
+
+registerTranscript
+	self environment registerTranscript: HLTranscriptHandler
+! !
+
 HLManager class instanceVariableNames: 'current'!
 
 !HLManager class methodsFor: 'accessing'!
@@ -1344,8 +1354,10 @@ current
 
 !HLManager class methodsFor: 'initialization'!
 
-initialize
-	self current appendToJQuery: 'body' asJQuery
+setup
+	self current 
+		setup;
+		appendToJQuery: 'body' asJQuery
 ! !
 
 !HLManager class methodsFor: 'instance creation'!
@@ -1391,6 +1403,12 @@ show
 	self appendToJQuery: 'body' asJQuery
 ! !
 
+!HLModalWidget methodsFor: 'private'!
+
+giveFocusToButton: aButton
+	aButton asJQuery focus
+! !
+
 !HLModalWidget methodsFor: 'rendering'!
 
 hasButtons
@@ -1412,7 +1430,7 @@ renderButtonsOn: html
 				with: 'Confirm';
 				onClick: [ self confirm ] ].
 
-	confirmButton asJQuery focus
+	self giveFocusToButton:confirmButton
 !
 
 renderContentOn: html
@@ -1519,12 +1537,19 @@ confirm
 	self actionBlock value: input asJQuery val
 ! !
 
+!HLRequestWidget methodsFor: 'private'!
+
+giveFocusToButton: aButton
+! !
+
 !HLRequestWidget methodsFor: 'rendering'!
 
 renderMainOn: html
 	super renderMainOn: html.
 	input := html textarea.
-	input asJQuery val: self value
+	input asJQuery 
+		val: self value;
+		focus
 ! !
 
 HLModalWidget subclass: #HLProgressWidget

+ 89 - 20
st/Helios-Debugger.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Debugger'!
+Smalltalk createPackage: 'Helios-Debugger'!
 Object subclass: #HLContextInspectorDecorator
 	instanceVariableNames: 'context'
 	package: 'Helios-Debugger'!
@@ -53,6 +53,9 @@ I am the main widget for the Helios debugger.!
 
 codeWidget
 	^ codeWidget ifNil: [ codeWidget := HLDebuggerCodeWidget new
+		model: (HLDebuggerCodeModel new
+			debuggerModel: self model;
+			yourself);
 		browserModel: self model;
 		yourself ]
 !
@@ -143,6 +146,26 @@ on: aMethodContext
 		yourself
 ! !
 
+HLCodeModel subclass: #HLDebuggerCodeModel
+	instanceVariableNames: 'debuggerModel'
+	package: 'Helios-Debugger'!
+
+!HLDebuggerCodeModel methodsFor: 'accessing'!
+
+debuggerModel
+	^ debuggerModel
+!
+
+debuggerModel: anObject
+	debuggerModel := anObject
+! !
+
+!HLDebuggerCodeModel methodsFor: 'actions'!
+
+doIt: aString
+	^ self debuggerModel evaluate: aString
+! !
+
 HLBrowserCodeWidget subclass: #HLDebuggerCodeWidget
 	instanceVariableNames: ''
 	package: 'Helios-Debugger'!
@@ -181,18 +204,13 @@ highlightNode: aNode
 	| token |
 	
 	aNode ifNotNil: [
-		token := self editor getTokenAt: #{ 
-			'line' -> (aNode position x - 1). 
-			'ch' -> aNode position y 
-		}.
-
 		self
 			clearHighlight;
-			addStopAt: aNode position x - 1.
+			addStopAt: aNode positionStart x - 1.
 
 		self editor 
-			setSelection: #{ 'line' -> (aNode position x - 1). 'ch' -> token start }
-			to: #{ 'line' -> (aNode position x - 1). 'ch' -> token end } ]
+			setSelection: #{ 'line' -> (aNode positionStart x - 1). 'ch' -> (aNode positionStart y - 1) }
+			to: #{ 'line' -> (aNode positionEnd x - 1). 'ch' -> (aNode positionEnd y) } ]
 !
 
 observeBrowserModel
@@ -224,7 +242,7 @@ HLToolModel subclass: #HLDebuggerModel
 	instanceVariableNames: 'rootContext currentContext contexts'
 	package: 'Helios-Debugger'!
 !HLDebuggerModel commentStamp!
-I am a model for Helios debugging.
+I am a model for debugging Amber code in Helios.
 
 My instances hold a reference to an `AIContext` instance, built from a `MethodContext`. The context should be the root of the context stack.!
 
@@ -264,6 +282,17 @@ rootContext
 
 restart
 	self interpreter restart.
+	self flushInnerContexts.
+	
+	self announcer announce: (HLDebuggerStepped new
+		context: self currentContext;
+		yourself)
+!
+
+skip
+	self interpreter skip.
+	self flushInnerContexts.
+	
 	self announcer announce: (HLDebuggerStepped new
 		context: self currentContext;
 		yourself)
@@ -271,6 +300,8 @@ restart
 
 stepOver
 	self interpreter stepOver.
+	self flushInnerContexts.
+	
 	self announcer announce: (HLDebuggerStepped new
 		context: self currentContext;
 		yourself)
@@ -280,6 +311,14 @@ where
 	self announcer announce: HLDebuggerWhere new
 ! !
 
+!HLDebuggerModel methodsFor: 'evaluating'!
+
+evaluate: aString
+	^ self environment 
+		interpret: aString 
+		inContext: self currentContext
+! !
+
 !HLDebuggerModel methodsFor: 'initialization'!
 
 initializeContexts
@@ -296,7 +335,18 @@ initializeContexts
 !
 
 initializeFromContext: aMethodContext
-	rootContext := AIContext fromMethodContext: aMethodContext.
+	rootContext := (AIContext fromMethodContext: aMethodContext).
+	self initializeContexts
+! !
+
+!HLDebuggerModel methodsFor: 'private'!
+
+flushInnerContexts
+	"When stepping, the inner contexts are not relevent anymore,
+	and can be flushed"
+	
+	self currentContext innerContext: nil.
+	rootContext := self currentContext.
 	self initializeContexts
 ! !
 
@@ -308,7 +358,7 @@ on: aMethodContext
 		yourself
 ! !
 
-ErrorHandler subclass: #HLErrorHandler
+Object subclass: #HLErrorHandler
 	instanceVariableNames: ''
 	package: 'Helios-Debugger'!
 
@@ -334,12 +384,6 @@ onErrorHandled
 		remove
 ! !
 
-!HLErrorHandler class methodsFor: 'error handling'!
-
-handleError: anError
-	^ self new handleError: anError
-! !
-
 HLToolListWidget subclass: #HLStackListWidget
 	instanceVariableNames: ''
 	package: 'Helios-Debugger'!
@@ -356,12 +400,26 @@ label
 
 !HLStackListWidget methodsFor: 'actions'!
 
+observeModel
+	super observeModel.
+	
+	self model announcer 
+		on: HLDebuggerStepped
+		send: #onDebuggerStepped:
+		to: self
+!
+
 restart
 	self model restart
 !
 
 selectItem: aContext
-   	self model currentContext: aContext
+   	self model currentContext: aContext.
+	super selectItem: aContext
+!
+
+skip
+	self model skip
 !
 
 stepOver
@@ -372,6 +430,13 @@ where
 	self model where
 ! !
 
+!HLStackListWidget methodsFor: 'reactions'!
+
+onDebuggerStepped: anAnnouncement
+	items := nil.
+	self refresh
+! !
+
 !HLStackListWidget methodsFor: 'rendering'!
 
 renderButtonsOn: html
@@ -389,6 +454,10 @@ renderButtonsOn: html
 			html button 
 				class: 'btn stepOver';
 				with: 'Step over';
-				onClick: [ self stepOver ] ]
+				onClick: [ self stepOver ].
+			html button 
+				class: 'btn skip';
+				with: 'Skip';
+				onClick: [ self skip ] ]
 ! !
 

+ 13 - 1
st/Helios-Exceptions.st

@@ -1,9 +1,21 @@
-Smalltalk current createPackage: 'Helios-Exceptions'!
+Smalltalk createPackage: 'Helios-Exceptions'!
 Error subclass: #HLError
 	instanceVariableNames: ''
 	package: 'Helios-Exceptions'!
+!HLError commentStamp!
+I am the abstract superclass of all Helios-specific errors.!
 
 HLError subclass: #HLChangeForbidden
 	instanceVariableNames: ''
 	package: 'Helios-Exceptions'!
+!HLChangeForbidden commentStamp!
+I get signaled when a (often user) requested change is forbidden. A confirmation message can then be displayed to the user.
+
+See `HLModel >> withChangesDo:`.!
+
+HLError subclass: #HLListItemNotFound
+	instanceVariableNames: ''
+	package: 'Helios-Exceptions'!
+!HLListItemNotFound commentStamp!
+I get signaled by a `HLListWidget` when a non-existing item in the list is activated.!
 

+ 439 - 0
st/Helios-Helpers.st

@@ -0,0 +1,439 @@
+Smalltalk createPackage: 'Helios-Helpers'!
+Object subclass: #HLClassifier
+	instanceVariableNames: 'next method'
+	package: 'Helios-Helpers'!
+!HLClassifier commentStamp!
+I am an abstract class implementing a link in a `chain of responsibility` pattern.
+
+Subclasses are in charge of classifying a method according to multiple strategies.!
+
+!HLClassifier methodsFor: 'accessing'!
+
+method
+	^ method
+!
+
+method: anObject
+	method := anObject.
+	self next
+		ifNotNil: [ :nextLink | nextLink method: anObject ]
+!
+
+next
+	^ next
+!
+
+next: anObject
+	next := anObject
+! !
+
+!HLClassifier methodsFor: 'private'!
+
+doClassify
+	self subclassResponsibility
+! !
+
+!HLClassifier methodsFor: 'protocol'!
+
+classify
+	self next ifNil: [ ^ false ].
+	
+	^ self doClassify
+		ifTrue: [ true ]
+		ifFalse: [ self next classify ]
+! !
+
+HLClassifier subclass: #HLAccessorClassifier
+	instanceVariableNames: ''
+	package: 'Helios-Helpers'!
+!HLAccessorClassifier commentStamp!
+I am a classifier checking the method selector matches an instance variable name.!
+
+!HLAccessorClassifier methodsFor: 'private'!
+
+doClassify
+	| names selector |
+	
+	names := method methodClass allInstanceVariableNames.
+	selector := method selector.
+	
+	(selector last = ':')
+		ifTrue: [ "selector might be a setter"
+			selector := selector allButLast ].
+	
+	(names includes: selector)
+		ifFalse: [ ^ false ].
+		
+	method protocol: 'accessing'.
+	^ true.
+! !
+
+HLClassifier subclass: #HLImplementorClassifier
+	instanceVariableNames: ''
+	package: 'Helios-Helpers'!
+!HLImplementorClassifier commentStamp!
+I am a classifier checking the other implementations of the same selector and choose the protocol the most populated.!
+
+!HLImplementorClassifier methodsFor: 'private'!
+
+doClassify
+	| currentClass |
+	currentClass := method methodClass.
+	
+	[ currentClass superclass isNil ] whileFalse: [
+		currentClass := currentClass superclass.
+		(currentClass includesSelector: method selector)
+			ifTrue: [ 
+				method protocol: (currentClass >> method selector) protocol.
+				^ true ]].
+	
+	^ false.
+! !
+
+HLClassifier subclass: #HLPrefixClassifier
+	instanceVariableNames: 'prefixMapping'
+	package: 'Helios-Helpers'!
+!HLPrefixClassifier commentStamp!
+I am classifier checking the method selector to know if it begins with a known prefix.!
+
+!HLPrefixClassifier methodsFor: 'initialization'!
+
+buildPrefixDictionary
+	prefixMapping := Dictionary new.
+	prefixMapping 
+		at: 'test' put: 'tests';
+	 	at: 'bench' put: 'benchmarking';
+	 	at: 'copy' put: 'copying';
+		at: 'initialize' put: 'initialization';
+		at: 'accept' put: 'visitor';
+		at: 'visit' put: 'visitor';
+		at: 'signal' put: 'signalling';
+		at: 'parse' put: 'parsing';
+		at: 'add' put: 'adding';
+		at: 'is' put: 'testing';
+		at: 'as' put: 'converting';
+		at: 'new' put: 'instance creation'.
+!
+
+initialize
+	super initialize.
+
+	self buildPrefixDictionary
+! !
+
+!HLPrefixClassifier methodsFor: 'private'!
+
+doClassify
+	prefixMapping keysAndValuesDo: [ :prefix :protocol |
+		(method selector beginsWith: prefix)
+			ifTrue: [
+				method protocol: protocol.
+				^ true ]].
+	^ false.
+! !
+
+HLClassifier subclass: #HLSuperclassClassifier
+	instanceVariableNames: ''
+	package: 'Helios-Helpers'!
+!HLSuperclassClassifier commentStamp!
+I am a classifier checking the superclass chain to find a matching selector.!
+
+!HLSuperclassClassifier methodsFor: 'private'!
+
+doClassify
+	| protocolBag methods protocolToUse counter |
+	
+	protocolBag := Dictionary new.
+	methods := HLReferencesModel new implementorsOf: method selector.
+	methods
+		ifEmpty: [ ^ false ]
+		ifNotEmpty: [
+			methods 
+				do: [ :aMethod || protocol |
+					protocol := aMethod method protocol.
+					(method methodClass = aMethod methodClass)
+						ifFalse: [
+						((protocol first = '*') or: [ protocol = method defaultProtocol ])
+							ifFalse: [ 
+								protocolBag 
+									at: protocol 
+									put: (protocolBag at: protocol ifAbsent: [ 0 ]) + 1 ] ] ] ].
+			
+	protocolBag ifEmpty: [ ^ false ].
+	protocolToUse := nil.
+	counter := 0.
+	protocolBag keysAndValuesDo: [ :key :value | value > counter 
+		ifTrue: [
+			counter := value.
+			protocolToUse := key ] ].
+	method protocol: protocolToUse.
+	^ true
+! !
+
+Object subclass: #HLGenerationOutput
+	instanceVariableNames: 'sourceCodes protocol targetClass'
+	package: 'Helios-Helpers'!
+!HLGenerationOutput commentStamp!
+I am a simple data object used to store the result of a generation process.!
+
+!HLGenerationOutput methodsFor: 'accessing'!
+
+protocol
+	^ protocol
+!
+
+protocol: aString
+	protocol := aString
+!
+
+sourceCodes
+	^ sourceCodes
+!
+
+sourceCodes: aCollection
+	sourceCodes := aCollection
+!
+
+targetClass
+	^ targetClass
+!
+
+targetClass: aClass
+	targetClass := aClass
+! !
+
+!HLGenerationOutput methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	
+	sourceCodes := OrderedCollection new
+! !
+
+!HLGenerationOutput methodsFor: 'protocol'!
+
+addSourceCode: aString
+	sourceCodes add: aString
+!
+
+compile
+	sourceCodes do: [ :methodSourceCode |
+		(targetClass includesSelector: methodSourceCode selector)
+			ifFalse: [ 
+				targetClass 
+					compile: methodSourceCode sourceCode
+					protocol: protocol ] ]
+! !
+
+Object subclass: #HLMethodClassifier
+	instanceVariableNames: 'firstClassifier'
+	package: 'Helios-Helpers'!
+!HLMethodClassifier commentStamp!
+I am in charge of categorizing methods following this strategy:
+
+- is it an accessor?
+- is it overriding a superclass method?
+- is it starting with a know prefix?
+- how are categorized the other implementations?!
+
+!HLMethodClassifier methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	
+	self setupClassifiers
+!
+
+setupClassifiers
+	self addClassifier: HLImplementorClassifier new.
+	self addClassifier: HLPrefixClassifier new.
+	self addClassifier: HLSuperclassClassifier new.
+	self addClassifier: HLAccessorClassifier new
+! !
+
+!HLMethodClassifier methodsFor: 'private'!
+
+addClassifier: aClassifier
+	aClassifier next: firstClassifier.
+	firstClassifier := aClassifier
+! !
+
+!HLMethodClassifier methodsFor: 'protocol'!
+
+classify: aMethod
+	firstClassifier
+		method: aMethod;
+		classify
+!
+
+classifyAll: aCollectionOfMethods
+	aCollectionOfMethods do: [ :method |
+		self classify: method ]
+! !
+
+Object subclass: #HLMethodGenerator
+	instanceVariableNames: 'output'
+	package: 'Helios-Helpers'!
+!HLMethodGenerator commentStamp!
+I am the abstract super class of the method generators.
+
+My main method is `generate` which produce an `output` object!
+
+!HLMethodGenerator methodsFor: 'accessing'!
+
+class: aClass
+	output targetClass: aClass
+!
+
+output
+	^ output
+! !
+
+!HLMethodGenerator methodsFor: 'initialization'!
+
+initialize
+	super initialize.
+	
+	output := HLGenerationOutput new
+! !
+
+!HLMethodGenerator methodsFor: 'protocol'!
+
+generate
+	output targetClass ifNil: [ self error: 'class should not be nil'].
+! !
+
+HLMethodGenerator subclass: #HLAccessorsGenerator
+	instanceVariableNames: ''
+	package: 'Helios-Helpers'!
+!HLAccessorsGenerator commentStamp!
+I am a generator used to compile the getters/setters of a class!
+
+!HLAccessorsGenerator methodsFor: 'double-dispatch'!
+
+accessorProtocolForObject
+	output protocol: 'accessing'
+!
+
+accessorsForObject
+	| sources |
+	
+	sources := OrderedCollection new.
+	output targetClass instanceVariableNames sorted do: [ :each | 
+		sources 
+			add: (self getterFor: each);
+			add: (self setterFor: each) ].
+	output sourceCodes: sources
+! !
+
+!HLAccessorsGenerator methodsFor: 'private'!
+
+getterFor: anInstanceVariable
+	^ HLMethodSourceCode new
+		selector:anInstanceVariable;
+		sourceCode: (String streamContents: [ :stream |
+		stream << anInstanceVariable.
+		stream cr tab.
+		stream << '^ ' << anInstanceVariable ])
+!
+
+setterFor: anInstanceVariable
+	^ HLMethodSourceCode new
+		selector: anInstanceVariable, ':';
+		sourceCode: (String streamContents: [ :stream |
+		stream << anInstanceVariable << ': anObject'.
+		stream cr tab.
+		stream << anInstanceVariable << ' := anObject' ])
+! !
+
+!HLAccessorsGenerator methodsFor: 'protocol'!
+
+generate
+	super generate.
+	
+	output targetClass 
+		accessorsSourceCodesWith: self;
+		accessorProtocolWith: self
+! !
+
+HLMethodGenerator subclass: #HLInitializeGenerator
+	instanceVariableNames: ''
+	package: 'Helios-Helpers'!
+!HLInitializeGenerator commentStamp!
+I am used to double-dispatch the `initialize` method(s) generation.
+
+Usage:
+
+    ^ HLInitializeGenerator new
+        class: aClass;
+        generate;
+        output
+
+I am a disposable object!
+
+!HLInitializeGenerator methodsFor: 'double-dispatch'!
+
+initializeForObject
+	output addSourceCode: self initializeMethodForObject
+!
+
+initializeProtocolForObject
+	output protocol: 'initialization'
+! !
+
+!HLInitializeGenerator methodsFor: 'private'!
+
+generateInitializeCodeForObject	
+	^ String streamContents: [ :str || instVars size |
+		instVars := output targetClass instanceVariableNames sorted.
+		size := instVars size.
+		str << 'initialize'.
+		str cr tab << 'super initialize.';cr.
+		str cr tab.
+		instVars withIndexDo: [ :name :index |
+			index ~= 1 ifTrue: [ str cr tab ].
+			str << name << ' := nil'.
+			index ~= size ifTrue: [ str << '.' ] ] ].
+!
+
+initializeMethodForObject	
+	^ HLMethodSourceCode new
+		selector: 'initialize';
+		sourceCode: self generateInitializeCodeForObject;
+		yourself
+! !
+
+!HLInitializeGenerator methodsFor: 'protocol'!
+
+generate
+	super generate.
+	
+	output targetClass 
+		initializeSourceCodesWith: self;
+		initializeProtocolWith: self
+! !
+
+Object subclass: #HLMethodSourceCode
+	instanceVariableNames: 'selector sourceCode'
+	package: 'Helios-Helpers'!
+!HLMethodSourceCode commentStamp!
+I am a simple data object keeping track of the information about a method that will be compiled at the end of the generation process!
+
+!HLMethodSourceCode methodsFor: 'accessing'!
+
+selector
+	^ selector
+!
+
+selector: aSelector
+	selector := aSelector
+!
+
+sourceCode
+	^ sourceCode
+!
+
+sourceCode: aString
+	sourceCode := aString
+! !
+

+ 8 - 31
st/Helios-Inspector.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Inspector'!
+Smalltalk createPackage: 'Helios-Inspector'!
 HLNavigationListWidget subclass: #HLInspectorDisplayWidget
 	instanceVariableNames: 'model'
 	package: 'Helios-Inspector'!
@@ -25,9 +25,9 @@ renderContentOn: html
 selectionDisplayString
 	|selection|
 	selection := model selection.
-    ^ (model variables keys includes: selection)
-    	ifTrue:[(model instVarObjectAt: selection) printString]
-      	ifFalse:['']
+    ^ (model variables includesKey: selection)
+    	ifTrue:[ (model instVarObjectAt: selection) printString ]
+      	ifFalse:[ '' ]
 ! !
 
 Object subclass: #HLInspectorModel
@@ -37,7 +37,7 @@ Object subclass: #HLInspectorModel
 !HLInspectorModel methodsFor: 'accessing'!
 
 announcer
-	^ announcer ifNil: [announcer := Announcer new ]
+	^ announcer ifNil: [ announcer := Announcer new ]
 !
 
 code
@@ -111,29 +111,6 @@ subscribe: aWidget
 	aWidget subscribeTo: self announcer
 ! !
 
-!HLInspectorModel methodsFor: 'reactions'!
-
-onKeyDown: anEvent
-
-	<if(anEvent.ctrlKey) {
-		if(anEvent.keyCode === 80) { //ctrl+p
-			self._printIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 68) { //ctrl+d
-			self._doIt();
-			anEvent.preventDefault();
-			return false;
-		}
-		if(anEvent.keyCode === 73) { //ctrl+i
-			self._inspectIt();
-			anEvent.preventDefault();
-			return false;
-		}
-	}>
-! !
-
 !HLInspectorModel class methodsFor: 'actions'!
 
 on: anEnvironment
@@ -287,6 +264,7 @@ variablesWidget
 
 inspect: anObject
 	self model inspect: anObject on: self.
+	self codeWidget receiver: anObject.
     
 	self 
     	refreshVariablesWidget;
@@ -349,7 +327,6 @@ onInspectIt
 !
 
 onInstanceVariableSelected
-	self codeWidget receiver: self model selectedInstVarObject.
 	self refreshDisplayWidget
 !
 
@@ -417,8 +394,8 @@ tabPriority
 
 inspect: anObject
 	self new
-		inspect: anObject;
-		openAsTab
+		openAsTab;
+		inspect: anObject
 ! !
 
 !HLInspector class methodsFor: 'initialization'!

+ 21 - 6
st/Helios-KeyBindings.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-KeyBindings'!
+Smalltalk createPackage: 'Helios-KeyBindings'!
 Object subclass: #HLBinding
 	instanceVariableNames: 'key label'
 	package: 'Helios-KeyBindings'!
@@ -294,7 +294,7 @@ errorStatus
 evaluate: aString	
 	[ self callback value: aString ]
 		on: Error
-		do: [:ex |
+		do: [ :ex |
 			self input asJQuery 
 				one: 'keydown' 
 				do: [ self clearStatus ].
@@ -473,7 +473,10 @@ setupEvents
 
 initialize
 	super initialize.
-	helper := HLKeyBinderHelperWidget on: self.
+	helper := HLKeyBinderHelperWidget on: self
+!
+
+setupHelper
 	helper 	
 		renderStart;
 		renderCog
@@ -533,8 +536,13 @@ selectedBinding
 
 !HLKeyBinderHelperWidget methodsFor: 'actions'!
 
+deactivate
+	self keyBinder deactivate
+!
+
 hide
 	('.', self cssClass) asJQuery remove.
+	'#overlay' asJQuery remove.
 	self showCog
 !
 
@@ -563,7 +571,7 @@ showWidget: aWidget
 
 renderBindingActionFor: aBinding on: html
 	html span class: 'command'; with: [
-		html span 
+		html strong 
 			class: 'label'; 
 			with: aBinding shortcut asLowercase.
   		html a 
@@ -597,12 +605,19 @@ renderCog
 !
 
 renderContentOn: html
+	html div 
+		id: 'overlay';
+		class: 'light';
+		onClick: [ self deactivate ].
+	
 	html div class: self cssClass; with: [
-      	self renderLabelOn:html.
+      	self renderLabelOn: html.
 		html div
 			id: self mainId;
 			with: [ self renderSelectedBindingOn: html ].
-		self renderCloseOn: html ]
+		self renderCloseOn: html ].
+		
+	':focus' asJQuery blur
 !
 
 renderLabelOn: html

+ 1 - 1
st/Helios-Layout.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Layout'!
+Smalltalk createPackage: 'Helios-Layout'!
 HLWidget subclass: #HLContainer
 	instanceVariableNames: 'splitter'
 	package: 'Helios-Layout'!

+ 30 - 29
st/Helios-References.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-References'!
+Smalltalk createPackage: 'Helios-References'!
 Object subclass: #HLMethodReference
 	instanceVariableNames: 'selector methodClass'
 	package: 'Helios-References'!
@@ -284,25 +284,11 @@ allMethods
 	^ self methodsCache
 !
 
-allSelectors
-	^ (self allMethods 
-		collect: [ :each | each selector ])
-		asSet
-!
-
 classReferencesOf: aString
 	"Answer all methods referencing the class named aString"
 	
-	| references |
-	
-	references := OrderedCollection new.
-	
-	self classesAndMetaclasses do: [ :each |
-		each methodDictionary values do: [ :method |
-			(method referencedClasses includes: aString) ifTrue: [
-				references add: method ] ] ].
-				
-	^ references
+	^self allMethods select: [ :each |
+			(each referencedClasses includes: aString) ].
 !
 
 classesAndMetaclasses
@@ -333,6 +319,24 @@ sendersOf: aString
 
 !HLReferencesModel methodsFor: 'actions'!
 
+openClassNamed: aString
+	| browser |
+	
+	self withChangesDo: [
+		browser := HLBrowser openAsTab.
+		browser openClassNamed: aString ]
+!
+
+openMethod
+	| browser |
+	
+	self selectedMethod ifNil: [ ^ self ].
+	
+	self withChangesDo: [
+		browser := HLBrowser openAsTab.
+		browser openMethod: self selectedMethod ]
+!
+
 search: aString
 	self updateCaches.
 	
@@ -345,13 +349,11 @@ search: aString
 
 classesAndMetaclassesCache
 	classesAndMetaclassesCache ifNil: [ self updateClassesAndMetaclassesCache ].
-	
 	^ classesAndMetaclassesCache
 !
 
 methodsCache
 	methodsCache ifNil: [ self updateMethodsCache ].
-	
 	^ methodsCache
 !
 
@@ -362,20 +364,19 @@ updateCaches
 !
 
 updateClassesAndMetaclassesCache
-	classesAndMetaclassesCache := self environment classes 
-		inject: OrderedCollection new 
-		into: [ :acc :each |
-			acc 
+	classesAndMetaclassesCache := OrderedCollection new.
+	
+	self environment classes do: [ :each |
+		classesAndMetaclassesCache
 				add: each; 
-				add: each class;
-				yourself ]
+				add: each class ]
 !
 
 updateMethodsCache
-	methodsCache := self classesAndMetaclasses
-		inject: OrderedCollection new
-		into: [ :acc :each |
-			acc, each methods ]
+	methodsCache := OrderedCollection new.
+	
+	self classesAndMetaclasses
+		do: [ :each | methodsCache addAll: each methods ]
 ! !
 
 !HLReferencesModel methodsFor: 'testing'!

+ 10 - 10
st/Helios-Transcript.st

@@ -1,4 +1,4 @@
-Smalltalk current createPackage: 'Helios-Transcript'!
+Smalltalk createPackage: 'Helios-Transcript'!
 HLWidget subclass: #HLTranscript
 	instanceVariableNames: 'textarea'
 	package: 'Helios-Transcript'!
@@ -71,26 +71,26 @@ transcripts
 	^ transcripts ifNil: [ transcripts := OrderedCollection new ]
 ! !
 
-!HLTranscriptHandler class methodsFor: 'initialization'!
-
-initialize
-	Transcript register: self
-! !
-
-!HLTranscriptHandler class methodsFor: 'registration'!
+!HLTranscriptHandler class methodsFor: 'printing'!
 
 clear
 	self transcripts do: [ :each |
 		each clear ]
 !
 
-register: aTranscript
-	self transcripts add: aTranscript
+cr
+	self transcripts do: [ :each | each cr ]
 !
 
 show: aString
 	self transcripts do: [ :each |
 		each show: aString ]
+! !
+
+!HLTranscriptHandler class methodsFor: 'registration'!
+
+register: aTranscript
+	self transcripts add: aTranscript
 !
 
 unregister: aTranscript

Some files were not shown because too many files changed in this diff