Merged Jakub Nesveda's refactoring_custom into master.
authorJan Vrany <jan.vrany@fit.cvut.cz>
Sun, 14 Jun 2015 09:54:32 +0100
changeset 834 ad13c243d9c6
parent 459 ed694c60f831 (diff)
parent 833 297eb38e4eee (current diff)
child 835 e6c018be0875
Merged Jakub Nesveda's refactoring_custom into master.
.hgtags
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgid	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,6 @@
+changeset:   360:0a4845a0c211
+parent:      357:6d1b45736520
+user:        Jan Vrany <jan.vrany@fit.cvut.cz>
+date:        Mon Dec 15 20:46:27 2014 +0000
+summary:     Update to catchup changes in libtool: refactoring to support multiple lint warnings at line
+
--- a/.hgtags	Sun Jun 14 09:46:51 2015 +0100
+++ b/.hgtags	Sun Jun 14 09:54:32 2015 +0100
@@ -1,1 +1,8 @@
+a27be88be57fe3d2ec05f2c08cf9baa9f22c7a14 expecco_2_7_0
 ce462903d43b4e1396691c65a4c24875dc1c4b16 thesis_submission
+a27be88be57fe3d2ec05f2c08cf9baa9f22c7a14 expecco_2_7_0
+feba6ee5c81409691496b92dabd87217d18adf11 expecco_2_7_0
+feba6ee5c81409691496b92dabd87217d18adf11 expecco_2_7_0
+3542abc630fa233edd1aae6244227ae417c69ea5 expecco_2_7_0
+3542abc630fa233edd1aae6244227ae417c69ea5 expecco_2_7_0
+c7340c8fe8adbd072fd8d397ea3469ab67723e5b expecco_2_7_0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Make.proto	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,243 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# The Makefile as generated by this Make.proto supports the following targets:
+#    make         - compile all st-files to a classLib
+#    make clean   - clean all temp files
+#    make clobber - clean all
+#
+# This file contains definitions for Unix based platforms.
+# It shares common definitions with the win32-make in Make.spec.
+
+#
+# position (of this package) in directory hierarchy:
+# (must point to ST/X top directory, for tools and includes)
+TOP=../..
+INCLUDE_TOP=$(TOP)/..
+
+# subdirectories where targets are to be made:
+SUBDIRS=
+
+
+# subdirectories where Makefiles are to be made:
+# (only define if different from SUBDIRS)
+# ALLSUBDIRS=
+
+REQUIRED_SUPPORT_DIRS=
+
+# if your embedded C code requires any system includes,
+# add the path(es) here:,
+# ********** OPTIONAL: MODIFY the next lines ***
+# LOCALINCLUDES=-Ifoo -Ibar
+LOCALINCLUDES= -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser -I$(INCLUDE_TOP)/stx/goodies/regex -I$(INCLUDE_TOP)/stx/goodies/sunit -I$(INCLUDE_TOP)/stx/libbasic -I$(INCLUDE_TOP)/stx/libbasic2 -I$(INCLUDE_TOP)/stx/libbasic3 -I$(INCLUDE_TOP)/stx/libcomp -I$(INCLUDE_TOP)/stx/libhtml -I$(INCLUDE_TOP)/stx/libjava -I$(INCLUDE_TOP)/stx/libjava/tools -I$(INCLUDE_TOP)/stx/libtool -I$(INCLUDE_TOP)/stx/libview -I$(INCLUDE_TOP)/stx/libview2 -I$(INCLUDE_TOP)/stx/libwidg -I$(INCLUDE_TOP)/stx/libwidg2
+
+
+# if you need any additional defines for embedded C code,
+# add them here:,
+# ********** OPTIONAL: MODIFY the next lines ***
+# LOCALDEFINES=-Dfoo -Dbar -DDEBUG
+LOCALDEFINES=
+
+LIBNAME=libstx_goodies_smallsense
+STCLOCALOPT='-package=$(PACKAGE)' -I. $(LOCALINCLUDES) $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES) -headerDir=.  -varPrefix=$(LIBNAME)
+
+
+# ********** OPTIONAL: MODIFY the next line ***
+# additional C-libraries that should be pre-linked with the class-objects
+LD_OBJ_LIBS=
+LOCAL_SHARED_LIBS=
+
+
+# ********** OPTIONAL: MODIFY the next line ***
+# additional C targets or libraries should be added below
+LOCAL_EXTRA_TARGETS=
+
+OBJS= $(COMMON_OBJS) $(UNIX_OBJS)
+
+
+
+all:: preMake classLibRule postMake
+
+pre_objs::  
+
+
+
+
+# Update SVN revision in package definition class
+ifneq (,$(findstring .svn,$(wildcard .svn)))
+.svnversion: *.st
+	if [ -d .svn ]; then \
+		rev=$(shell svnversion -n); \
+		echo -n $$rev > .svnversion; \
+	else \
+		echo -n exported > .svnversion; \
+	fi
+
+stx_goodies_smallsense.o: stx_goodies_smallsense.st .svnversion
+	@if [ -d .svn ]; then \
+		rev2="$(shell printf "%-16s" $$(cat .svnversion))"; \
+		echo "  [SV]  Expanding svnRevisionNo in $1.st"; \
+		sed -e "s/\"\$$SVN\-Revision:\".*\"\$$\"/\"\$$SVN-Revision:\"\'$$rev2\'\"\$$\"/g" $< > .stx_goodies_smallsense.svn.st; \
+	fi
+	$(MAKE) CC="$(CLASSLIB_CC)" OPT="$(OPT)" SEPINITCODE="$(SEPINITCODE)" STC="$(STC)" STFILE=.stx_goodies_smallsense.svn $(C_RULE);
+	sed -i -e "s/\".stx_goodies_smallsense.svn.st\");/\"\stx_goodies_smallsense.st\");/g" .stx_goodies_smallsense.svn.c
+	$(MAKE) .stx_goodies_smallsense.svn.$(O)
+	@mv .stx_goodies_smallsense.svn.$(O) stx_goodies_smallsense.$(O)
+endif
+
+
+
+# Enforce recompilation of package definition class if Mercurial working
+# copy state changes. Together with --guessVersion it ensures that package
+# definition class always contains correct binary revision string.
+ifneq (**NOHG**, $(shell hg root 2> /dev/null || echo -n '**NOHG**'))
+stx_goodies_smallsense.$(O): $(shell hg root)/.hg/dirstate
+endif
+
+
+
+
+# run default testsuite for this package
+test: $(TOP)/goodies/builder/reports
+	$(MAKE) -C $(TOP)/goodies/builder/reports -f Makefile.init
+	$(TOP)/goodies/builder/reports/report-runner.sh -D . -r Builder::TestReport -p $(PACKAGE)
+
+
+
+# add more install actions here
+install::
+
+# add more install actions for aux-files (resources) here
+installAux::
+
+# add more preMake actions here
+preMake::
+
+# add more postMake actions here
+postMake:: cleanjunk
+
+# build all mandatory prerequisite packages (containing superclasses) for this package
+prereq:
+	cd ../../libbasic && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../refactoryBrowser/helpers && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../refactoryBrowser/parser && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../regex && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libbasic2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libbasic3 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libcomp && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libui && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libview && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libview2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../refactoryBrowser/browser && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../sunit && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libwidg && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../refactoryBrowser/lint && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libhtml && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libwidg2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd ../../libtool && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+
+
+
+# build all packages containing referenced classes for this package
+# they are not needed to compile the package (but later, to load it)
+references:
+
+
+cleanjunk::
+	-rm -f *.s *.s2
+
+clean::
+	-rm -f *.o *.H
+
+clobber:: clean
+	-rm -f *.so *.dll
+
+
+# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
+$(OUTDIR)SmallSense__AbstractDIalog.$(O) SmallSense__AbstractDIalog.$(H): SmallSense__AbstractDIalog.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractSearchProcessor.$(O) SmallSense__AbstractSearchProcessor.$(H): SmallSense__AbstractSearchProcessor.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CodeHighlightingService.$(O) SmallSense__CodeHighlightingService.$(H): SmallSense__CodeHighlightingService.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__BackgroundSourceProcessingService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeHighlightingService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CodeNavigationService.$(O) SmallSense__CodeNavigationService.$(H): SmallSense__CodeNavigationService.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeNavigationService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionContext.$(O) SmallSense__CompletionContext.$(H): SmallSense__CompletionContext.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionController.$(O) SmallSense__CompletionController.$(H): SmallSense__CompletionController.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg/EditTextViewCompletionSupport.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionEngine.$(O) SmallSense__CompletionEngine.$(H): SmallSense__CompletionEngine.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionResult.$(O) SmallSense__CompletionResult.$(H): SmallSense__CompletionResult.st $(INCLUDE_TOP)/stx/libbasic/Collection.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/OrderedCollection.$(H) $(INCLUDE_TOP)/stx/libbasic/SequenceableCollection.$(H) $(INCLUDE_TOP)/stx/libbasic/SortedCollection.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionView.$(O) SmallSense__CompletionView.$(H): SmallSense__CompletionView.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview/DisplaySurface.$(H) $(INCLUDE_TOP)/stx/libview/GraphicsMedium.$(H) $(INCLUDE_TOP)/stx/libview/SimpleView.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CriticsWindow.$(O) SmallSense__CriticsWindow.$(H): SmallSense__CriticsWindow.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__EditService.$(O) SmallSense__EditService.$(H): SmallSense__EditService.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__EditSupport.$(O) SmallSense__EditSupport.$(H): SmallSense__EditSupport.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Info.$(O) SmallSense__Info.$(H): SmallSense__Info.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Manager.$(O) SmallSense__Manager.$(H): SmallSense__Manager.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__NavigatorStep.$(O) SmallSense__NavigatorStep.$(H): SmallSense__NavigatorStep.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PO.$(O) SmallSense__PO.$(H): SmallSense__PO.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeIndex.$(O) SmallSense__ParseTreeIndex.$(H): SmallSense__ParseTreeIndex.st $(INCLUDE_TOP)/stx/libbasic/Collection.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/OrderedCollection.$(H) $(INCLUDE_TOP)/stx/libbasic/SequenceableCollection.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeIndexEntry.$(O) SmallSense__ParseTreeIndexEntry.$(H): SmallSense__ParseTreeIndexEntry.st $(INCLUDE_TOP)/stx/libbasic/Magnitude.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeInspector.$(O) SmallSense__ParseTreeInspector.$(H): SmallSense__ParseTreeInspector.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/HierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SelectorNode.$(O) SmallSense__SelectorNode.$(H): SmallSense__SelectorNode.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libcomp/ParseNode.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SettingsAppl.$(O) SmallSense__SettingsAppl.$(H): SmallSense__SettingsAppl.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/AbstractSettingsApplication.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkChecker.$(O) SmallSense__SmalltalkChecker.$(H): SmallSense__SmalltalkChecker.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint/SmalllintChecker.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkInferencerParameters.$(O) SmallSense__SmalltalkInferencerParameters.$(H): SmallSense__SmalltalkInferencerParameters.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkLintService.$(O) SmallSense__SmalltalkLintService.$(H): SmallSense__SmalltalkLintService.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__BackgroundSourceProcessingService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkParseNodeVisitor.$(O) SmallSense__SmalltalkParseNodeVisitor.$(H): SmallSense__SmalltalkParseNodeVisitor.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkParser.$(O) SmallSense__SmalltalkParser.$(H): SmallSense__SmalltalkParser.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libcomp/AbstractSyntaxHighlighter.$(H) $(INCLUDE_TOP)/stx/libcomp/Parser.$(H) $(INCLUDE_TOP)/stx/libcomp/Scanner.$(H) $(INCLUDE_TOP)/stx/libcomp/SyntaxHighlighter.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkQuickFixer.$(O) SmallSense__SmalltalkQuickFixer.$(H): SmallSense__SmalltalkQuickFixer.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkSyntaxHighlighter.$(O) SmallSense__SmalltalkSyntaxHighlighter.$(H): SmallSense__SmalltalkSyntaxHighlighter.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libcomp/AbstractSyntaxHighlighter.$(H) $(INCLUDE_TOP)/stx/libcomp/Parser.$(H) $(INCLUDE_TOP)/stx/libcomp/Scanner.$(H) $(INCLUDE_TOP)/stx/libcomp/SyntaxHighlighter.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkUnacceptedMethodEnvironment.$(O) SmallSense__SmalltalkUnacceptedMethodEnvironment.$(H): SmallSense__SmalltalkUnacceptedMethodEnvironment.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/BrowserEnvironment.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternMatcher.$(O) SmallSense__TokenPatternMatcher.$(H): SmallSense__TokenPatternMatcher.st $(INCLUDE_TOP)/stx/goodies/regex/RxMatcher.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternParser.$(O) SmallSense__TokenPatternParser.$(H): SmallSense__TokenPatternParser.st $(INCLUDE_TOP)/stx/goodies/regex/RxCharSetParser.$(H) $(INCLUDE_TOP)/stx/goodies/regex/RxParser.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternToken.$(O) SmallSense__TokenPatternToken.$(H): SmallSense__TokenPatternToken.st $(INCLUDE_TOP)/stx/goodies/regex/RxsNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternTokenSet.$(O) SmallSense__TokenPatternTokenSet.$(H): SmallSense__TokenPatternTokenSet.st $(INCLUDE_TOP)/stx/goodies/regex/RxsCharSet.$(H) $(INCLUDE_TOP)/stx/goodies/regex/RxsNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenStream.$(O) SmallSense__TokenStream.$(H): SmallSense__TokenStream.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Type.$(O) SmallSense__Type.$(H): SmallSense__Type.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TypeHolder.$(O) SmallSense__TypeHolder.$(H): SmallSense__TypeHolder.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)stx_goodies_smallsense.$(O) stx_goodies_smallsense.$(H): stx_goodies_smallsense.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractJavaCompletionEngine.$(O) SmallSense__AbstractJavaCompletionEngine.$(H): SmallSense__AbstractJavaCompletionEngine.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractListDialog.$(O) SmallSense__AbstractListDialog.$(H): SmallSense__AbstractListDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassInfo.$(O) SmallSense__ClassInfo.$(H): SmallSense__ClassInfo.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__Info.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassPO.$(O) SmallSense__ClassPO.$(H): SmallSense__ClassPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassSearchProcessor.$(O) SmallSense__ClassSearchProcessor.$(H): SmallSense__ClassSearchProcessor.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassType.$(O) SmallSense__ClassType.$(H): SmallSense__ClassType.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__Type.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompositeProcessor.$(O) SmallSense__CompositeProcessor.$(H): SmallSense__CompositeProcessor.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ConstantPO.$(O) SmallSense__ConstantPO.$(H): SmallSense__ConstantPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__GenericEditSupport.$(O) SmallSense__GenericEditSupport.$(H): SmallSense__GenericEditSupport.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__EditSupport.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ImplementorSearchProcessor.$(O) SmallSense__ImplementorSearchProcessor.$(H): SmallSense__ImplementorSearchProcessor.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaEditSupport.$(O) SmallSense__JavaEditSupport.$(H): SmallSense__JavaEditSupport.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__EditSupport.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaImportPO.$(O) SmallSense__JavaImportPO.$(H): SmallSense__JavaImportPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodBindingPO.$(O) SmallSense__MethodBindingPO.$(H): SmallSense__MethodBindingPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodInfo.$(O) SmallSense__MethodInfo.$(H): SmallSense__MethodInfo.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__Info.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodPO.$(O) SmallSense__MethodPO.$(H): SmallSense__MethodPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PackagePO.$(O) SmallSense__PackagePO.$(H): SmallSense__PackagePO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PluggablePO.$(O) SmallSense__PluggablePO.$(H): SmallSense__PluggablePO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PluggableSearchProcessor.$(O) SmallSense__PluggableSearchProcessor.$(H): SmallSense__PluggableSearchProcessor.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkCompletionEngine.$(O) SmallSense__SmalltalkCompletionEngine.$(H): SmallSense__SmalltalkCompletionEngine.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkEditSupport.$(O) SmallSense__SmalltalkEditSupport.$(H): SmallSense__SmalltalkEditSupport.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__EditSupport.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkInferencer.$(O) SmallSense__SmalltalkInferencer.$(H): SmallSense__SmalltalkInferencer.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__SmalltalkParseNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkParseNodeFinder.$(O) SmallSense__SmalltalkParseNodeFinder.$(H): SmallSense__SmalltalkParseNodeFinder.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__SmalltalkParseNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SnippetPO.$(O) SmallSense__SnippetPO.$(H): SmallSense__SnippetPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__UnionType.$(O) SmallSense__UnionType.$(H): SmallSense__UnionType.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__SmalltalkInferencerParameters.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__Type.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__UnknownType.$(O) SmallSense__UnknownType.$(H): SmallSense__UnknownType.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__Type.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__VariableBindingPO.$(O) SmallSense__VariableBindingPO.$(H): SmallSense__VariableBindingPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__VariablePO.$(O) SmallSense__VariablePO.$(H): SmallSense__VariablePO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractJavaCompletionEngineSimple.$(O) SmallSense__AbstractJavaCompletionEngineSimple.$(H): SmallSense__AbstractJavaCompletionEngineSimple.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractSearchDialog.$(O) SmallSense__AbstractSearchDialog.$(H): SmallSense__AbstractSearchDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractSelectDialog.$(O) SmallSense__AbstractSelectDialog.$(H): SmallSense__AbstractSelectDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__GroovyEditSupport.$(O) SmallSense__GroovyEditSupport.$(H): SmallSense__GroovyEditSupport.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__EditSupport.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__JavaEditSupport.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaCompletionEngine.$(O) SmallSense__JavaCompletionEngine.$(H): SmallSense__JavaCompletionEngine.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaConstructorPO.$(O) SmallSense__JavaConstructorPO.$(H): SmallSense__JavaConstructorPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__MethodPO.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodKeywordRestPO.$(O) SmallSense__MethodKeywordRestPO.$(H): SmallSense__MethodKeywordRestPO.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__MethodPO.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__PO.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libwidg2/AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)/stx/libwidg2/CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassSearchDialog.$(O) SmallSense__ClassSearchDialog.$(H): SmallSense__ClassSearchDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSearchDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaCompletionEngineSimple.$(O) SmallSense__JavaCompletionEngineSimple.$(H): SmallSense__JavaCompletionEngineSimple.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractJavaCompletionEngineSimple.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodSearchDialog.$(O) SmallSense__MethodSearchDialog.$(H): SmallSense__MethodSearchDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSearchDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Navigator.$(O) SmallSense__Navigator.$(H): SmallSense__Navigator.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSearchDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PackageSelectDialog.$(O) SmallSense__PackageSelectDialog.$(H): SmallSense__PackageSelectDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSelectDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ProtocolSelectDialog.$(O) SmallSense__ProtocolSelectDialog.$(H): SmallSense__ProtocolSelectDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractSelectDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__GroovyCompletionEngineSimple.$(O) SmallSense__GroovyCompletionEngineSimple.$(H): SmallSense__GroovyCompletionEngineSimple.st $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__AbstractJavaCompletionEngineSimple.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/SmallSense__JavaCompletionEngineSimple.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint/RBBasicLintRule.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint/RBBlockLintRule.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint/RBContainsSmalltalkXEOLCommentRule.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint/RBLintRule.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/lint/RBTransformationRule.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBBlockNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBMethodNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBProgramNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBStatementNode.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBValueNode.$(H) $(INCLUDE_TOP)/stx/libbasic/Collection.$(H) $(INCLUDE_TOP)/stx/libbasic/CompiledCode.$(H) $(INCLUDE_TOP)/stx/libbasic/ConfigurableFeatures.$(H) $(INCLUDE_TOP)/stx/libbasic/Dictionary.$(H) $(INCLUDE_TOP)/stx/libbasic/ExecutableFunction.$(H) $(INCLUDE_TOP)/stx/libbasic/IdentityDictionary.$(H) $(INCLUDE_TOP)/stx/libbasic/Method.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/Set.$(H) $(INCLUDE_TOP)/stx/libbasic/UserPreferences.$(H) $(INCLUDE_TOP)/stx/libcomp/AssignmentNode.$(H) $(INCLUDE_TOP)/stx/libcomp/BlockNode.$(H) $(INCLUDE_TOP)/stx/libcomp/MessageNode.$(H) $(INCLUDE_TOP)/stx/libcomp/ParseErrorNode.$(H) $(INCLUDE_TOP)/stx/libcomp/ParseNode.$(H) $(INCLUDE_TOP)/stx/libcomp/Parser.$(H) $(INCLUDE_TOP)/stx/libcomp/PrimaryNode.$(H) $(INCLUDE_TOP)/stx/libcomp/PrimitiveNode.$(H) $(INCLUDE_TOP)/stx/libcomp/ReturnNode.$(H) $(INCLUDE_TOP)/stx/libcomp/Scanner.$(H) $(INCLUDE_TOP)/stx/libcomp/StatementNode.$(H) $(INCLUDE_TOP)/stx/libcomp/VariableNode.$(H) $(INCLUDE_TOP)/stx/libhtml/HTMLDocumentFrame.$(H) $(INCLUDE_TOP)/stx/libhtml/HTMLDocumentView.$(H) $(INCLUDE_TOP)/stx/libtool/DebugView.$(H) $(INCLUDE_TOP)/stx/libtool/InspectorView.$(H) $(INCLUDE_TOP)/stx/libtool/MultiViewToolApplication.$(H) $(INCLUDE_TOP)/stx/libtool/SystemBrowser.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__BackgroundSourceProcessingService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeCompletionService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeHighlightingService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeNavigationService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__CodeViewService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__Inspector2.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__LintService.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__NavigationState.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__NewSystemBrowser.$(H) $(INCLUDE_TOP)/stx/libtool/WorkspaceApplication.$(H) $(INCLUDE_TOP)/stx/libview/DisplaySurface.$(H) $(INCLUDE_TOP)/stx/libview/GraphicsMedium.$(H) $(INCLUDE_TOP)/stx/libview/ModalBox.$(H) $(INCLUDE_TOP)/stx/libview/SimpleView.$(H) $(INCLUDE_TOP)/stx/libview/StandardSystemView.$(H) $(INCLUDE_TOP)/stx/libview/TopView.$(H) $(INCLUDE_TOP)/stx/libview/View.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(INCLUDE_TOP)/stx/libview2/ToolApplicationModel.$(H) $(INCLUDE_TOP)/stx/libwidg/DialogBox.$(H) $(INCLUDE_TOP)/stx/libwidg/EditTextView.$(H) $(INCLUDE_TOP)/stx/libwidg/EditTextViewCompletionSupport.$(H) $(INCLUDE_TOP)/stx/libwidg/ListView.$(H) $(INCLUDE_TOP)/stx/libwidg/TextView.$(H) $(STCHDR)
+
+# ENDMAKEDEPEND --- do not remove this line
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Make.spec	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,218 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# This file contains specifications which are common to all platforms.
+#
+
+# Do NOT CHANGE THESE DEFINITIONS
+# (otherwise, ST/X will have a hard time to find out the packages location from its packageID,
+#  to find the source code of a class and to find the library for a package)
+MODULE=stx
+MODULE_DIR=goodies/smallsense
+PACKAGE=$(MODULE):$(MODULE_DIR)
+
+
+# Argument(s) to the stc compiler (stc --usage).
+#  -headerDir=. : create header files locally
+#                (if removed, they will be created as common
+#  -Pxxx       : defines the package
+#  -Zxxx       : a prefix for variables within the classLib
+#  -Dxxx       : defines passed to to CC for inline C-code
+#  -Ixxx       : include path passed to CC for inline C-code
+#  +optspace   : optimized for space
+#  +optspace2  : optimized more for space
+#  +optspace3  : optimized even more for space
+#  +optinline  : generate inline code for some ST constructs
+#  +inlineNew  : additionally inline new
+#  +inlineMath : additionally inline some floatPnt math stuff
+#
+# ********** OPTIONAL: MODIFY the next line(s) ***
+# STCLOCALOPTIMIZATIONS=+optinline +inlineNew
+# STCLOCALOPTIMIZATIONS=+optspace3
+STCLOCALOPTIMIZATIONS=+optspace3
+
+
+# Argument(s) to the stc compiler (stc --usage).
+#  -warn            : no warnings
+#  -warnNonStandard : no warnings about ST/X extensions
+#  -warnEOLComments : no warnings about EOL comment extension
+#  -warnPrivacy     : no warnings about privateClass extension
+#  -warnUnused      : no warnings about unused variables
+#
+# ********** OPTIONAL: MODIFY the next line(s) ***
+# STCWARNINGS=-warn
+# STCWARNINGS=-warnNonStandard
+# STCWARNINGS=-warnEOLComments
+STCWARNINGS=-warnNonStandard
+
+COMMON_CLASSES= \
+	SmallSense::AbstractDIalog \
+	SmallSense::AbstractSearchProcessor \
+	SmallSense::CodeHighlightingService \
+	SmallSense::CodeNavigationService \
+	SmallSense::CompletionContext \
+	SmallSense::CompletionController \
+	SmallSense::CompletionEngine \
+	SmallSense::CompletionResult \
+	SmallSense::CompletionView \
+	SmallSense::CriticsWindow \
+	SmallSense::EditService \
+	SmallSense::EditSupport \
+	SmallSense::Info \
+	SmallSense::Manager \
+	SmallSense::NavigatorStep \
+	SmallSense::PO \
+	SmallSense::ParseTreeIndex \
+	SmallSense::ParseTreeIndexEntry \
+	SmallSense::ParseTreeInspector \
+	SmallSense::SelectorNode \
+	SmallSense::SettingsAppl \
+	SmallSense::SmalltalkChecker \
+	SmallSense::SmalltalkInferencerParameters \
+	SmallSense::SmalltalkLintService \
+	SmallSense::SmalltalkParseNodeVisitor \
+	SmallSense::SmalltalkParser \
+	SmallSense::SmalltalkQuickFixer \
+	SmallSense::SmalltalkSyntaxHighlighter \
+	SmallSense::SmalltalkUnacceptedMethodEnvironment \
+	SmallSense::TokenPatternMatcher \
+	SmallSense::TokenPatternParser \
+	SmallSense::TokenPatternToken \
+	SmallSense::TokenPatternTokenSet \
+	SmallSense::TokenStream \
+	SmallSense::Type \
+	SmallSense::TypeHolder \
+	stx_goodies_smallsense \
+	SmallSense::AbstractJavaCompletionEngine \
+	SmallSense::AbstractListDialog \
+	SmallSense::ClassInfo \
+	SmallSense::ClassPO \
+	SmallSense::ClassSearchProcessor \
+	SmallSense::ClassType \
+	SmallSense::CompositeProcessor \
+	SmallSense::ConstantPO \
+	SmallSense::GenericEditSupport \
+	SmallSense::ImplementorSearchProcessor \
+	SmallSense::JavaEditSupport \
+	SmallSense::JavaImportPO \
+	SmallSense::MethodBindingPO \
+	SmallSense::MethodInfo \
+	SmallSense::MethodPO \
+	SmallSense::PackagePO \
+	SmallSense::PluggablePO \
+	SmallSense::PluggableSearchProcessor \
+	SmallSense::SmalltalkCompletionEngine \
+	SmallSense::SmalltalkEditSupport \
+	SmallSense::SmalltalkInferencer \
+	SmallSense::SmalltalkParseNodeFinder \
+	SmallSense::SnippetPO \
+	SmallSense::UnionType \
+	SmallSense::UnknownType \
+	SmallSense::VariableBindingPO \
+	SmallSense::VariablePO \
+	SmallSense::AbstractJavaCompletionEngineSimple \
+	SmallSense::AbstractSearchDialog \
+	SmallSense::AbstractSelectDialog \
+	SmallSense::GroovyEditSupport \
+	SmallSense::JavaCompletionEngine \
+	SmallSense::JavaConstructorPO \
+	SmallSense::MethodKeywordRestPO \
+	SmallSense::ClassSearchDialog \
+	SmallSense::JavaCompletionEngineSimple \
+	SmallSense::MethodSearchDialog \
+	SmallSense::Navigator \
+	SmallSense::PackageSelectDialog \
+	SmallSense::ProtocolSelectDialog \
+	SmallSense::GroovyCompletionEngineSimple \
+
+
+
+
+COMMON_OBJS= \
+    $(OUTDIR_SLASH)SmallSense__AbstractDIalog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__AbstractSearchProcessor.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CodeHighlightingService.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CodeNavigationService.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CompletionContext.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CompletionController.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CompletionEngine.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CompletionResult.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CompletionView.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CriticsWindow.$(O) \
+    $(OUTDIR_SLASH)SmallSense__EditService.$(O) \
+    $(OUTDIR_SLASH)SmallSense__EditSupport.$(O) \
+    $(OUTDIR_SLASH)SmallSense__Info.$(O) \
+    $(OUTDIR_SLASH)SmallSense__Manager.$(O) \
+    $(OUTDIR_SLASH)SmallSense__NavigatorStep.$(O) \
+    $(OUTDIR_SLASH)SmallSense__PO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ParseTreeIndex.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ParseTreeIndexEntry.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ParseTreeInspector.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SelectorNode.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SettingsAppl.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkChecker.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkInferencerParameters.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkLintService.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkParseNodeVisitor.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkParser.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkQuickFixer.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkSyntaxHighlighter.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkUnacceptedMethodEnvironment.$(O) \
+    $(OUTDIR_SLASH)SmallSense__TokenPatternMatcher.$(O) \
+    $(OUTDIR_SLASH)SmallSense__TokenPatternParser.$(O) \
+    $(OUTDIR_SLASH)SmallSense__TokenPatternToken.$(O) \
+    $(OUTDIR_SLASH)SmallSense__TokenPatternTokenSet.$(O) \
+    $(OUTDIR_SLASH)SmallSense__TokenStream.$(O) \
+    $(OUTDIR_SLASH)SmallSense__Type.$(O) \
+    $(OUTDIR_SLASH)SmallSense__TypeHolder.$(O) \
+    $(OUTDIR_SLASH)stx_goodies_smallsense.$(O) \
+    $(OUTDIR_SLASH)SmallSense__AbstractJavaCompletionEngine.$(O) \
+    $(OUTDIR_SLASH)SmallSense__AbstractListDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ClassInfo.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ClassPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ClassSearchProcessor.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ClassType.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CompositeProcessor.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ConstantPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__GenericEditSupport.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ImplementorSearchProcessor.$(O) \
+    $(OUTDIR_SLASH)SmallSense__JavaEditSupport.$(O) \
+    $(OUTDIR_SLASH)SmallSense__JavaImportPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__MethodBindingPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__MethodInfo.$(O) \
+    $(OUTDIR_SLASH)SmallSense__MethodPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__PackagePO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__PluggablePO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__PluggableSearchProcessor.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkCompletionEngine.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkEditSupport.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkInferencer.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SmalltalkParseNodeFinder.$(O) \
+    $(OUTDIR_SLASH)SmallSense__SnippetPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__UnionType.$(O) \
+    $(OUTDIR_SLASH)SmallSense__UnknownType.$(O) \
+    $(OUTDIR_SLASH)SmallSense__VariableBindingPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__VariablePO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__AbstractJavaCompletionEngineSimple.$(O) \
+    $(OUTDIR_SLASH)SmallSense__AbstractSearchDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__AbstractSelectDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__GroovyEditSupport.$(O) \
+    $(OUTDIR_SLASH)SmallSense__JavaCompletionEngine.$(O) \
+    $(OUTDIR_SLASH)SmallSense__JavaConstructorPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__MethodKeywordRestPO.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ClassSearchDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__JavaCompletionEngineSimple.$(O) \
+    $(OUTDIR_SLASH)SmallSense__MethodSearchDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__Navigator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__PackageSelectDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__ProtocolSelectDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__GroovyCompletionEngineSimple.$(O) \
+    $(OUTDIR_SLASH)extensions.$(O) \
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile.init	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,27 @@
+#
+# DO NOT EDIT
+#
+# make uses this file (Makefile) only, if there is no
+# file named "makefile" (lower-case m) in the same directory.
+# My only task is to generate the real makefile and call make again.
+# Thereafter, I am no longer used and needed.
+#
+# MACOSX caveat:
+#   as filenames are not case sensitive (in a default setup),
+#   we cannot use the above trick. Therefore, this file is now named
+#   "Makefile.init", and you have to execute "make -f Makefile.init" to
+#   get the initial makefile.  This is now also done by the toplevel CONFIG
+#   script.
+
+.PHONY: run
+
+run: makefile
+	$(MAKE) -f makefile
+
+#only needed for the definition of $(TOP)
+include Make.proto
+
+makefile: mf
+
+mf:
+	$(TOP)/rules/stmkmf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/README.md	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,83 @@
+# SmallSense
+
+*Developer's productivity plugin for Smalltalk/X IDE.*
+
+## About
+
+**SmallSense** is a set of tools that speed up development and make
+Smalltalk programming even more fun. Features:
+
+* **Code-completion** -- a fast code completion system for Smalltalk using both static and runtime type inference.
+* **Syntax-driven editing** -- a nice little feature that helps you with editing and formatting the code, all syntax- and formater-preferences aware!
+* **Instant static analysis** -- to detect & fix common errors and code smells as you type
+
+There are many more features already on the TODO list :-) Besides, *SmallSense*
+provides (limited) support for Java anf Groovy as well (to be used together with
+[STX:LIBJAVA](1))
+
+## Installation
+
+### Stock Smalltalk/X (aka official version)
+
+Following instructruction are for stock Smalltalk/X 6.2.5 as downloaded from
+[eXept]. 
+
+**1. Remove old SmallSense:** remove directory `/stx/goodies/smallsense`. Smalltalk/X may come with it's own version/fork of SmallSense. 
+
+**2. Check out SmallSense:** 
+
+    hg clone https://bitbucket.org/janvrany/stx-goodies-smallsense stx/goodies/smallsense
+    
+**3. Compile it (optional):**
+
+On UNIX: 
+
+    make -C /stx/goodies/smallsense -f Makefile.init
+    
+On Windows: 
+
+    cd stx\goodies\smallsense && bmake
+    
+**4. Load it:** to load it into an IDE, evaluate:
+
+    Smalltalk loadPackage:'stx:goodies/smallsense'
+    
+You may want to add the above to your startup script (`$HOME/.smalltalk/p_$USER.rc) so SmallSense will be loaded automatically when you start Smalltalk/X. You may also want to turn on [method swizzling](4) there. 
+
+### Smalltalk/X jv-branch
+
+There's no need to install SmallSense into [Smalltalk/X jv-branch](3) as it is 
+loaded automatically when you start Smalltalk/X. 
+
+
+## Configuration
+
+After installing and loading SmallSense, you may want to configure it. To do so,
+open system settings and go to *Tools* ⊳ *SmallSense*.
+
+
+## Authors
+
+Developers:
+
+* Jan Vraný <jan . vrany [a] fit.cvut.cz>
+
+Contributors:
+
+* Jakub Zelenka (first version of code completion, type inference and syntax-error tolerant Smalltalk parser)
+
+## License
+
+The SmallSense is available under GNU Lesser General Public License.
+Please find full text of the license in file license.txt.
+For other licensing options, please contact the SmallSense author at
+jan.vrany { at } fit.cvut.cz.
+
+[1]: https://swing.fit.cvut.cz/projects/stx-libjava
+[2]: ftp://exept.de/download/stx/
+[3]: https://swing.fit.cvut.cz/projects/stx-jv
+[4]: https://bitbucket.org/janvrany/stx-goodies-smallsense/wiki/Swizzling.md
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractDIalog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,697 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SimpleDialog subclass:#AbstractDIalog
+	instanceVariableNames:'titleHolder buttons buttonsPanelView acceptEnabledHolder
+		optionsVisibleLabelHolder optionsVisibleHolder optionsPanelView'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!AbstractDIalog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractDIalog class methodsFor:'interface specs'!
+
+dialogSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractDIalog andSelector:#dialogSpec
+     SmallSense::AbstractDIalog new openInterface:#dialogSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: dialogSpec
+       window: 
+      (WindowSpec
+         label: 'Search...'
+         name: 'Search...'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 708 404)
+         menu: mainMenuSpec
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (ViewSpec
+             name: 'Layput'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             component: 
+            (SpecCollection
+               collection: (
+                (UISubSpecification
+                   name: 'Content'
+                   layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+                   minorKey: contentPaneSpec
+                 )
+                (UISubSpecification
+                   name: 'Options'
+                   layout: (LayoutFrame 0 0 -30 1 0 1 0 1)
+                   visibilityChannel: optionsVisibleHolder
+                   minorKey: optionsPaneSpec
+                   postBuildCallback: postBuildOptionsPanelView:
+                 )
+                )
+              
+             )
+           )
+          )
+        
+       )
+     )
+
+    "Modified: / 03-05-2014 / 00:49:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+windowSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractDIalog andSelector:#windowSpec
+     SmallSense::AbstractDIalog new openInterface:#windowSpec
+     SmallSense::AbstractDIalog open
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: windowSpec
+       window: 
+      (WindowSpec
+         label: 'Search...'
+         name: 'Search...'
+         labelChannel: titleHolder
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 708 404)
+         menu: mainMenuSpec
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (UISubSpecification
+             name: 'ContentPane'
+             layout: (LayoutFrame 10 0 0 0 -10 1 -40 1)
+             minorKey: dialogSpec
+           )
+          (UISubSpecification
+             name: 'ButtonsPane'
+             layout: (LayoutFrame 10 0 -40 1 -10 1 0 1)
+             minorKey: buttonsPaneSpec
+             keepSpaceForOSXResizeHandleH: true
+           )
+          )
+        
+       )
+     )
+! !
+
+!AbstractDIalog class methodsFor:'interface specs-content'!
+
+buttonsPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractDIalog andSelector:#buttonsPaneSpec
+     SmallSense::AbstractDIalog new openInterface:#buttonsPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: buttonsPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Search...'
+         name: 'Search...'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 708 38)
+         menu: mainMenuSpec
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (HorizontalPanelViewSpec
+             name: 'Buttons'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             horizontalLayout: okCancelBox
+             verticalLayout: center
+             horizontalSpace: 3
+             verticalSpace: 3
+             reverseOrderIfOKAtLeft: true
+             postBuildCallback: postBuildButtonsPanelView:
+           )
+          )
+        
+       )
+     )
+!
+
+contentPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractSearchDialog andSelector:#optionsPaneSpec
+     SmallSense::AbstractSearchDialog new openInterface:#optionsPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: contentPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Search ...'
+         name: 'Search Options...'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 634 40)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (LabelSpec
+             label: 'No content (override #contentPaneSpec)'
+             name: 'NoOptionsLabel'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             translateLabel: true
+           )
+          )
+        
+       )
+     )
+
+    "Created: / 02-05-2014 / 00:17:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+optionsPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractSearchDialog andSelector:#optionsPaneSpec
+     SmallSense::AbstractSearchDialog new openInterface:#optionsPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: optionsPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Search Options...'
+         name: 'Search Options...'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 634 40)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (LabelSpec
+             label: 'No options (override #optionsPaneSpec)'
+             name: 'NoOptionsLabel'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             translateLabel: true
+           )
+          )
+        
+       )
+     )
+!
+
+optionsShowHideLeftAlignedPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractDIalog andSelector:#optionsShowHideLeftAlignedPaneSpec
+     SmallSense::AbstractDIalog new openInterface:#optionsShowHideLeftAlignedPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: optionsShowHideLeftAlignedPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Show / Hide options'
+         name: 'Show / Hide options'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 452 20)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (LinkButtonSpec
+             label: 'Options'
+             name: 'ShowHideOptions'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             translateLabel: true
+             labelChannel: optionsVisibleLabelHolder
+             adjust: left
+             model: doOptionsShowOrHide
+           )
+          )
+        
+       )
+     )
+!
+
+optionsShowHideRightAlignedPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractDIalog andSelector:#optionsShowHideLeftAlignedPaneSpec
+     SmallSense::AbstractDIalog new openInterface:#optionsShowHideLeftAlignedPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: optionsShowHideLeftAlignedPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Show / Hide options'
+         name: 'Show / Hide options'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 452 20)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (LinkButtonSpec
+             label: 'Options'
+             name: 'ShowHideOptions'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             translateLabel: true
+             labelChannel: optionsVisibleLabelHolder
+             adjust: right
+             model: doOptionsShowOrHide
+           )
+          )
+        
+       )
+     )
+
+    "Created: / 03-05-2014 / 00:56:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractDIalog class methodsFor:'testing'!
+
+isAbstract
+    ^ self == SmallSense::AbstractDIalog
+! !
+
+!AbstractDIalog methodsFor:'accessing-defaults'!
+
+defaultTitle
+    ^ self subclassResponsibility
+
+    "Created: / 05-05-2014 / 23:38:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractDIalog methodsFor:'actions'!
+
+doOptionsShowOrHide
+    | optionsView optionsViewHeight otherView otherViewIsBelow layout |
+
+    optionsView := optionsPanelView.
+    optionsView superView subViews last == optionsView ifTrue:[ 
+        otherView := optionsView superView subViews before: optionsView.
+        otherViewIsBelow := false.
+    ] ifFalse:[
+        otherView := optionsView superView subViews after: optionsView.
+        otherViewIsBelow := true.
+    ].
+    self optionsVisibleHolder value ifFalse:[ 
+        "/ Show
+        self optionsVisibleHolder value: true.
+        optionsViewHeight := ((self class optionsPaneSpec at: 5) at: 9) at: 5.
+        otherViewIsBelow ifFalse:[
+            layout := otherView layout copy.
+            layout bottomOffset: (layout bottomOffset - optionsViewHeight).  
+            otherView  layout: layout.
+
+            layout := optionsView layout copy.
+            layout topOffset: (layout topOffset - optionsViewHeight).  
+            optionsView  layout: layout.
+        ] ifTrue:[ 
+            layout := optionsView layout copy.
+            layout bottomOffset: (layout bottomOffset + optionsViewHeight).  
+            optionsView  layout: layout.
+
+            layout := otherView layout copy.
+            layout topOffset: (layout topOffset + optionsViewHeight).  
+            otherView  layout: layout.
+        ].
+    ] ifTrue:[ 
+        "/ Hide
+        self optionsVisibleHolder value: false. 
+        optionsViewHeight := ((self class optionsPaneSpec at: 5) at: 9) at: 5.
+        otherViewIsBelow ifFalse:[
+            layout := otherView layout copy.
+            layout bottomOffset: (layout bottomOffset + optionsViewHeight).  
+            otherView  layout: layout.
+
+            layout := optionsView layout copy.
+            layout topOffset: (layout topOffset + optionsViewHeight).  
+            optionsView  layout: layout.
+        ] ifTrue:[ 
+            layout := optionsView layout copy.
+            layout bottomOffset: (layout bottomOffset - optionsViewHeight).  
+            optionsView  layout: layout.
+
+            layout := otherView layout copy.
+            layout topOffset: (layout topOffset - optionsViewHeight).  
+            otherView  layout: layout.
+        ].                                                                    
+    ].
+
+    "Modified: / 03-05-2014 / 00:27:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractDIalog methodsFor:'adding & removing components'!
+
+addButton: aButton
+    buttons add: aButton.
+    buttonsPanelView notNil ifTrue:[ 
+        buttonsPanelView addComponent: aButton.
+    ].
+
+    "Created: / 10-04-2012 / 20:49:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-04-2014 / 22:52:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtonAccept
+
+    ^self addButtonAcceptWithLabel: (resources string:'OK')
+
+    "Created: / 28-04-2014 / 22:51:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-01-2015 / 07:00:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtonAcceptWithLabel: label
+
+    ^self addButtonWithLabel: label action: [ self doAccept ] enablement: self acceptEnabledHolder.
+
+    "Created: / 29-01-2015 / 06:59:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtonCancel
+
+    ^self addButtonCancelWithLabel: (resources string:'Cancel')
+
+    "Created: / 28-04-2014 / 22:50:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-01-2015 / 07:00:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtonCancelWithLabel: label
+
+    ^self addButtonWithLabel: label action: [ self doCancel ]
+
+    "Created: / 29-01-2015 / 07:00:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtonWithLabel: label action: action
+    ^self addButtonWithLabel: label action: action enablement: true.
+
+    "Created: / 10-04-2012 / 20:50:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-04-2014 / 22:55:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtonWithLabel: label action: action enablement: enablement
+    | button |
+
+    button := Button label: label action: action.
+    button enableChannel: enablement.
+    ^self addButton: button.
+
+    "Created: / 28-04-2014 / 22:51:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractDIalog methodsFor:'aspects'!
+
+acceptEnabledHolder
+    <resource: #uiAspect>
+
+    "automatically generated by UIPainter ..."
+
+    "*** the code below creates a default model when invoked."
+    "*** (which may not be the one you wanted)"
+    "*** Please change as required and accept it in the browser."
+    "*** (and replace this comment by something more useful ;-)"
+
+    acceptEnabledHolder isNil ifTrue:[
+        acceptEnabledHolder := true asValue.
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/       acceptEnabledHolder addDependent:self.
+"/       acceptEnabledHolder onChangeSend:#acceptEnabledHolderChanged to:self.
+    ].
+    ^ acceptEnabledHolder.
+!
+
+optionsVisibleHolder
+    "return/create the 'optionsVisibleHolder' value holder (automatically generated)"
+
+    optionsVisibleHolder isNil ifTrue:[
+        optionsVisibleHolder := false asValue.
+        optionsVisibleHolder addDependent:self.
+    ].
+    ^ optionsVisibleHolder
+
+    "Modified: / 02-05-2014 / 00:26:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+optionsVisibleHolder:something
+    "set the 'optionsVisibleHolder' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    optionsVisibleHolder notNil ifTrue:[
+        oldValue := optionsVisibleHolder value.
+        optionsVisibleHolder removeDependent:self.
+    ].
+    optionsVisibleHolder := something.
+    optionsVisibleHolder notNil ifTrue:[
+        optionsVisibleHolder addDependent:self.
+    ].
+    newValue := optionsVisibleHolder value.
+    oldValue ~~ newValue ifTrue:[
+        self update:#value with:newValue from:optionsVisibleHolder.
+    ].
+!
+
+optionsVisibleLabelHolder
+    <resource: #uiAspect>
+
+    "automatically generated by UIPainter ..."
+
+    "*** the code below creates a default model when invoked."
+    "*** (which may not be the one you wanted)"
+    "*** Please change as required and accept it in the browser."
+    "*** (and replace this comment by something more useful ;-)"
+
+    optionsVisibleLabelHolder isNil ifTrue:[
+        optionsVisibleLabelHolder := (resources string: 'Options') asValue.
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/       optionsVisibleLabelHolder addDependent:self.
+"/       optionsVisibleLabelHolder onChangeSend:#optionsVisibleLabelHolderChanged to:self.
+    ].
+    ^ optionsVisibleLabelHolder.
+
+    "Modified: / 02-05-2014 / 00:25:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+titleHolder
+    "return/create the 'titleHolder' value holder (automatically generated)"
+
+    titleHolder isNil ifTrue:[
+        titleHolder := self defaultTitle asValue.
+        titleHolder addDependent:self.
+    ].
+    ^ titleHolder
+
+    "Modified: / 05-05-2014 / 23:38:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+titleHolder:something
+    "set the 'titleHolder' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    titleHolder notNil ifTrue:[
+        oldValue := titleHolder value.
+        titleHolder removeDependent:self.
+    ].
+    titleHolder := something.
+    titleHolder notNil ifTrue:[
+        titleHolder addDependent:self.
+    ].
+    newValue := titleHolder value.
+    oldValue ~~ newValue ifTrue:[
+        self update:#value with:newValue from:titleHolder.
+    ].
+! !
+
+!AbstractDIalog methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+    changedObject == optionsVisibleHolder ifTrue:[
+        self updateOptionsVisibleLabel.
+        ^ self.
+    ].     
+    ^ super update:something with:aParameter from:changedObject
+
+    "Created: / 02-05-2014 / 00:29:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateOptionsVisibleLabel
+    | label |
+
+    label := 
+        self optionsVisibleHolder value 
+            ifTrue:[ resources string: 'Hide options']
+            ifFalse:[ resources string: 'Options'].
+    label := label asText colorizeAllWith: Color blue.
+    self optionsVisibleLabelHolder value: label.
+
+    "Created: / 02-05-2014 / 00:29:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-05-2014 / 23:56:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractDIalog methodsFor:'hooks'!
+
+postBuildButtonsPanelView: aHorizontalPanelView
+    buttonsPanelView := aHorizontalPanelView.
+
+    "Created: / 28-04-2014 / 22:42:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+postBuildOptionsPanelView:aView
+    optionsPanelView := aView
+
+    "Modified: / 03-05-2014 / 00:00:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+postBuildWith: anUIBuilder
+    | w |
+
+    super postBuildWith: anUIBuilder.
+    self updateOptionsVisibleLabel.
+
+    buttons isEmpty ifTrue:[ 
+        | savedButtonsPanelView |
+
+        savedButtonsPanelView := buttonsPanelView.
+        buttonsPanelView := nil.                  
+        self addButtonCancel.    
+        self addButtonAccept.   
+        buttonsPanelView := savedButtonsPanelView.
+    ].
+
+    w := buttons inject: 0 into: [ :width :button | width max: (button preferredExtent x) ].
+    w := (w + 20) max: 100.
+    buttons do:[:button | 
+        button preferredExtent: w @ 25.
+        buttonsPanelView addComponent: button.  
+    ].
+
+    "Created: / 28-04-2014 / 22:53:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-01-2015 / 07:10:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractDIalog methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    buttons := OrderedCollection new.
+    "/ buttonsPanelView := nil.
+
+    super initialize.
+
+    "Modified: / 28-04-2014 / 22:49:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractDIalog class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractJavaCompletionEngine.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,218 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+CompletionEngine subclass:#AbstractJavaCompletionEngine
+	instanceVariableNames:'class method'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java'
+!
+
+!AbstractJavaCompletionEngine class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractJavaCompletionEngine class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::AbstractJavaCompletionEngine.
+! !
+
+!AbstractJavaCompletionEngine methodsFor:'completion-individual'!
+
+addClassesStartingWith: prefix
+    ^ self addClassesStartingWith:prefix matchFullName:false
+
+    "Created: / 03-10-2013 / 11:16:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-05-2014 / 07:25:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addClassesStartingWith:prefixArg filter: filter
+    ^ self addClassesStartingWith:prefixArg matchFullName:false filter: filter
+
+    "Created: / 07-08-2014 / 15:04:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addClassesStartingWith:prefixArg matchFullName:matchFullName 
+    ^ self addClassesStartingWith:prefixArg matchFullName:matchFullName filter: nil
+
+    "Created: / 15-05-2014 / 07:24:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 15:03:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addClassesStartingWith:prefixArg matchFullName:matchFullName filter: filter 
+    | prefix |
+
+    prefix := prefixArg.
+    matchFullName ifTrue:[
+        prefix := prefix copyReplaceAll:$. with:$/.
+    ].
+    context environment 
+        allClassesDo:[:cls | 
+            (cls isJavaClass and:[ cls isAnonymous not and:[filter isNil or:[filter value: cls]]]) ifTrue:[
+                | name  i |
+
+                matchFullName ifTrue:[
+                    (prefix isEmpty or:[cls binaryName startsWith:prefix]) ifTrue:[
+                        result add:((PO forClass:cls)
+                                    showPrefix:true;
+                                    yourself).
+                    ].
+                ] ifFalse:[
+                    name := cls lastName.
+                    i := name lastIndexOf:$/.
+                    prefix isEmptyOrNil ifTrue:[ 
+                        result add:(PO forClass:cls).
+                    ] ifFalse:[
+                        ((name size >= (i + prefix size)) 
+                            and:[
+                                (name at:i + 1) == prefix first 
+                                    and:[
+                                        (name at:i + prefix size) == prefix last 
+                                            and:[
+                                                (2 to:prefix size - 1) 
+                                                    allSatisfy:[:o | (name at:i + o) == (prefix at:o) ]
+                                            ]
+                                    ]
+                            ]) 
+                                ifTrue:[ result add:(PO forClass:cls). ].
+                    ]
+                ].
+            ].
+        ].
+
+    "Created: / 07-08-2014 / 15:03:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 16:05:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addConstructorsForClass: aJavaClass fullName: showFullName
+    aJavaClass selectorsAndMethodsDo:[:selector :method |
+        (selector first == $< and:[ selector startsWith: '<init>' ]) ifTrue:[
+            result add: ((JavaConstructorPO new initializeWithClass: aJavaClass selector: selector) showPrefix: showFullName)
+        ].
+    ].
+
+    "Created: / 15-05-2014 / 12:05:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addExceptionsStartingWith: prefix
+    "raise an error: this method should be implemented (TODO)"
+
+    ^ self addExceptionsStartingWith: prefix matchFullName: false
+
+    "Created: / 07-08-2014 / 14:59:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addExceptionsStartingWith: prefix matchFullName: matchFullName
+    ^ self addClassesStartingWith: prefix matchFullName: matchFullName filter: [ :cls | cls isThrowable ].
+
+    "Created: / 07-08-2014 / 15:04:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addFieldsForType: type
+    | seen |
+
+    type isUnknownType ifTrue:[ 
+        ^ self.
+    ].
+    seen := Set new.
+    type classesDo:[:initialCls |
+        (seen includes: initialCls) ifFalse:[
+            | cls |
+
+            cls := initialCls.
+            cls staticFields do:[:each | result add: (VariablePO classVariable: each name in: cls) ].
+            [ cls ~~ JavaObject and:[ (seen includes: cls) not ] ] whileTrue:[
+                seen add: cls.
+                cls fields do:[:each | result add: (VariablePO instanceVariable: each name in: cls) ].
+                cls := cls superclass.
+            ].
+        ]
+    ].
+
+    "Created: / 17-05-2014 / 20:37:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 22-05-2014 / 17:36:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addImportsStartingWith: prefix
+    | packages |
+
+    packages := Set new.
+
+    "/ Class imports...
+    context environment allClassesDo: [:cls |
+        cls isJavaClass ifTrue:[
+            | name |
+
+            name := cls javaName.
+            (cls isPublic and:[name startsWith: prefix]) ifTrue:[
+                result add: (JavaImportPO new import: name; klass: cls; yourself).
+                packages add: cls javaPackage.
+            ].
+        ]
+    ].
+    "/ Package imports...
+    packages do:[:each |
+        result add: (JavaImportPO new import: (each , '.*'))
+    ].
+
+    "Created: / 19-10-2013 / 17:54:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 14-05-2014 / 12:48:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsStartingWith: prefix
+    ^ self addMethodsStartingWith: prefix stripOff: nil filter: [:m | m isJavaMethod ]
+
+    "Created: / 03-10-2013 / 18:01:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-04-2014 / 21:37:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngine class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractJavaCompletionEngineSimple.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,566 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractJavaCompletionEngine subclass:#AbstractJavaCompletionEngineSimple
+	instanceVariableNames:'imports locals'
+	classVariableNames:'PatternPrimitiveType PatternReferenceType'
+	poolDictionaries:''
+	category:'SmallSense-Java'
+!
+
+AbstractJavaCompletionEngineSimple class instanceVariableNames:'PatternsForCompletion PatternsForAnalysis'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+!AbstractJavaCompletionEngineSimple class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractJavaCompletionEngineSimple class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    PatternPrimitiveType := '( [[:byte:]] | [[:short:]] | [[:int:]] | [[:long:]] | [[:float:]] | [[:double:]] | [[:char:]] | [[:boolean:]] )'.
+    PatternReferenceType := '( [[:Identifier:]]( \. [[:Identifier:]] )* )'
+
+    "Modified: / 19-05-2014 / 12:31:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple class methodsFor:'accessing'!
+
+patternsForAnalysis
+    PatternsForAnalysis isNil ifTrue:[
+        PatternsForAnalysis := self patternsFrom: self patternDefinitionsForAnalysis
+    ].
+    ^ PatternsForAnalysis
+
+    "Created: / 19-05-2014 / 11:56:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+patternsForCompletion
+    PatternsForCompletion isNil ifTrue:[
+        PatternsForCompletion := self patternsFrom: self patternDefinitionsForCompletion.  
+    ].
+    ^ PatternsForCompletion
+
+    "Created: / 14-05-2014 / 16:55:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-05-2014 / 11:56:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+patternsFrom: anArray
+    | patterns |
+
+    patterns := Dictionary new.
+    anArray pairWiseDo:[:key :def |
+        patterns at: key put: (TokenPatternParser parse: def)             
+    ].
+    ^ patterns
+
+    "Created: / 19-05-2014 / 11:55:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple class methodsFor:'accessing-definitions'!
+
+patternDefinitionsForAnalysis
+    ^ { 
+        #analyzeImport:                 . '[[:import:]] [[:Identifier:]] ( \. ([[:Identifier:]] | \*) )* ;' .
+        #analyzeLocalDecl:              .  '( ', PatternPrimitiveType , ' | ' , PatternReferenceType , ') [[:Identifier:]] ( = | ; )' .
+    }
+
+    "
+    self flush; patternsForAnalysis
+    "
+
+    "Created: / 19-05-2014 / 11:56:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-05-2014 / 10:23:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+patternDefinitionsForCompletion
+    ^ { 
+        #completeImport:                . '[[:import:]] ( [[:Identifier:]](\.[[:Identifier:]])*\.? )? [[:CARET:]]' .
+        #completeNew:                   . '[[:new:]] ( [[:Identifier:]](\.[[:Identifier:]])*\.?)? [[:CARET:]]' .
+        #completeLocalDef:              . '( ', PatternPrimitiveType , ' | ' , PatternReferenceType , ') [[:Identifier:]] [[:CARET:]]' .
+        #completeCatch:                 . '[[:catch:]] \( (' , PatternReferenceType , ' \.? )? [[:CARET:]]' .
+    }
+
+    "
+    self flush. self patternsForCompletion
+    "
+
+    "Created: / 19-05-2014 / 11:51:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 16:44:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::AbstractJavaCompletionEngineSimple.
+
+    "Modified: / 19-05-2014 / 11:23:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple class methodsFor:'utilities'!
+
+flush
+    PatternsForAnalysis := PatternsForCompletion := nil.
+    self subclassesDo:[:each | each flush ].
+
+    "Created: / 19-05-2014 / 11:57:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple methodsFor:'accessing'!
+
+patternsForAnalysis
+    ^ self class patternsForAnalysis
+
+    "Created: / 19-05-2014 / 13:06:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+patternsForCompletion
+    ^ self class patternsForCompletion
+
+    "Created: / 14-05-2014 / 17:02:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple methodsFor:'accessing-class'!
+
+scannerClass
+    "raise an error: must be redefined in concrete subclass(es)"
+
+    ^ self subclassResponsibility
+! !
+
+!AbstractJavaCompletionEngineSimple methodsFor:'analysis'!
+
+analyze
+    | scanner stream |
+
+    imports := OrderedCollection new.
+    locals := Dictionary new.
+    scanner := self scannerClass for: textView contents.
+    scanner allowRunawayString: true.  
+    stream := TokenStream on: scanner.
+    self patternsForAnalysis keysAndValuesDo:[ :action :pattern |
+        | matcher |
+
+        stream reset. "/ Reset the position
+        matcher := TokenPatternMatcher for: pattern.
+        matcher matchesOnStream: stream do:[:match | 
+            self perform: action with: match.
+        ].
+    ].
+
+    "Created: / 19-05-2014 / 13:06:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 21:18:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+analyzeImport: match
+
+    | import |
+
+    import := String streamContents: [ :s| 2 to: match size - 1 do:[:i | s nextPutAll: (match at: i) value asString ] ].
+    imports add: import
+
+    "Created: / 19-05-2014 / 13:43:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+analyzeLocalDecl: match
+    | typename name |
+
+    self assert: match size >= 3.
+
+    name := (match at: match size - 1) value.
+    typename := String streamContents:[ :s| 1 to: match size - 2 do:[:i | s nextPutAll: (match at: i) value asString ] ].
+
+    locals at: name put: typename.
+
+    "Created: / 23-05-2014 / 10:23:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple methodsFor:'completion-individual'!
+
+addSnippetsStartingWith: prefix
+    self scannerClass keywordTable keysDo:[:keyword |
+        (keyword startsWith: prefix) ifTrue:[
+            result add: (SnippetPO new value: keyword , ' ').        
+        ]
+    ]
+
+    "Created: / 18-05-2014 / 10:49:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addVariables
+    self addFieldsForType: self guessTypeOfThis.
+
+    locals keysDo:[:name | 
+        result add: (VariablePO variable: name) 
+    ].
+
+    "Created: / 17-05-2014 / 09:15:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-05-2014 / 16:45:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple methodsFor:'completion-private'!
+
+complete
+    | line col scanner stream tokens anyMatched |
+
+    line := textView listAt: textView cursorLine.
+    col := textView cursorCol.
+    line isNil ifTrue:[ ^ nil ].
+    line size < (col - 1) ifTrue:[ ^ nil ].
+
+    self analyze.
+
+    scanner := self scannerClass for: line string.
+    scanner allowRunawayString: true.  
+    stream := TokenStream on: scanner cursor: col - 1.
+    anyMatched := false.
+    self patternsForCompletion keysAndValuesDo:[ :action :pattern |
+        | matcher |
+
+        stream position: 0. "/ Reset the position
+        matcher := TokenPatternMatcher for: pattern.
+        matcher matchesOnStream: stream do:[:match | 
+            self perform: action with: match.
+            anyMatched := true.
+        ].
+    ].
+    anyMatched ifFalse:[ 
+        | caretI last lastI |
+
+        stream position: 0.
+        tokens := stream contents.
+        "/ At least there must be CARET token
+        tokens size == 1 ifTrue:[ ^ result ].
+        tokens first type == #CARET ifTrue:[ ^ result ].
+
+        "/ Find last token before CARET
+        caretI := 2.
+        [ (tokens at: caretI) type ~~ #CARET ] whileTrue:[ caretI := caretI + 1 ].
+        lastI := caretI - 1.
+        last := tokens at: lastI.
+
+        last type == #Identifier ifTrue:[
+            lastI == 1 ifTrue:[ 
+                "/ Only one token on line, complete local variable or receiver's field.
+                self completeSnippetsStartingWith: last value.
+                self completeLocalOrFieldIn: tokens before: caretI.
+            ] ifFalse:[ 
+                "/ If preceeding token is dot, complete method or field of the receiver.
+                (tokens at: lastI - 1) type == $. ifTrue:[ 
+                    self completeMethodOrFieldIn: tokens before: caretI.
+                ] ifFalse:[ 
+                    "/ Else try to complete field.
+                    self completeSnippetsStartingWith: last value.
+                    self completeLocalOrFieldIn: tokens before: caretI.
+                ].
+            ].
+        ] ifFalse:[
+        "/ Else if last token in dot, complete method or field of the receiver
+        last type == $. ifTrue:[ 
+            self completeMethodOrFieldIn: tokens before: caretI.
+        ]].
+    ].
+    ^ result
+
+    "Created: / 02-10-2013 / 13:55:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 21:19:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeCatch: match
+    | prefix |
+
+    match size == 3 ifTrue:[ 
+        self addExceptionsStartingWith: nil matchFullName: false.
+    ] ifFalse:[
+        match size == 4 ifTrue:[ 
+            prefix := (match at: 3) value asString.
+            self addExceptionsStartingWith: prefix matchFullName: prefix first isLowercase.
+        ] ifFalse:[ 
+            | last |
+
+            last := match size - 1"Carret token".
+            (match at: last) value == $. ifTrue:[ 
+                last := last - 1.
+            ].
+            prefix := String streamContents:[:s | 3 to: last do:[:i | s nextPutAll: (match at: i) value asString] ].    
+            self addExceptionsStartingWith: prefix matchFullName: true   
+        ].
+    ].
+
+    "Created: / 07-08-2014 / 14:59:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 16:10:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeImport: match
+    | prefix |
+
+    match size > 2 ifTrue:[ 
+        prefix := String streamContents:[:s | 2 to: match size - 1 do:[:i | s nextPutAll: (match at: i) value asString] ].
+        self addImportsStartingWith: prefix
+    ].
+
+    "Created: / 15-05-2014 / 06:57:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-05-2014 / 13:39:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeLocalDef: match
+    "Nothing to so here. Mainly to inhibit local variable/field completion here"
+
+    "Created: / 19-05-2014 / 12:34:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeLocalOrFieldIn: tokens before: caretTokenIndex
+    self addVariables
+
+    "Created: / 15-05-2014 / 18:53:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-05-2014 / 09:15:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeMethodOrFieldIn: tokens before: caretTokenIndex
+    | type dotIndex |
+
+    dotIndex := (tokens at: caretTokenIndex - 1) type == #Identifier ifTrue:[ caretTokenIndex - 2 ] ifFalse:[ caretTokenIndex - 1 ].  
+    self assert: (tokens at: dotIndex) type == $..
+    type := self guessTypeOfExpressionBefore: dotIndex in: tokens.
+    type isUnknownType ifFalse:[
+        self addMethodsForType: type.  
+        "/self addFieldsForType: type.
+    ] ifTrue:[ 
+        (tokens at: caretTokenIndex - 1) type == #Identifier ifTrue:[
+            | prefix |
+
+            prefix := (tokens at: caretTokenIndex - 1) value.
+            (prefix size >= 3 and:[ prefix ~= 'get' and:[prefix ~= 'set' ]]) ifTrue:[
+                self addMethodsStartingWith: prefix.
+            ].
+        ].
+    ].
+
+    "Created: / 15-05-2014 / 18:51:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-05-2014 / 13:16:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeNew: match
+    | prefix classes full |
+
+    match size < 2 ifTrue:[ 
+        ^ self.
+    ].
+
+    match size > 3 ifTrue:[ 
+        prefix := String streamContents:[:s | 2 to: match size - 1 do:[:i | s nextPutAll: (match at: i) value asString] ].
+        full := true.
+    ] ifFalse:[
+        match size < 3 ifTrue:[ ^ self ].
+        prefix := (match at: 2) value.
+        full := false.
+    ].
+    prefix replaceAll: $. with: $/.
+    classes := Set new.
+    context environment allClassesDo:[:cls |
+        (cls isJavaClass and:[cls isPublic]) ifTrue:[ 
+            full ifTrue:[ 
+                (cls binaryName startsWith: prefix) ifTrue:[ 
+                    classes add: cls.
+                ].
+            ] ifFalse:[ 
+                (cls lastName startsWith: prefix) ifTrue:[ 
+                    classes add: cls.
+                ].
+            ].
+        ].
+    ].
+
+    classes do:[:cls | 
+        self addConstructorsForClass: cls fullName: full.
+    ].
+
+    "Created: / 15-05-2014 / 07:16:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-05-2014 / 13:19:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeSnippetsStartingWith: prefix
+    self addSnippetsStartingWith: prefix
+
+    "Created: / 18-05-2014 / 10:48:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple methodsFor:'guesswork'!
+
+guessTypeOfExpressionBefore: end in: tokens
+    | i type |
+
+    i := end - 1.  
+
+    (tokens at: i) type == $) ifTrue:[ 
+        "/ OK, end of message send, scan for method name...
+        | nparens nargs name |
+
+        nparens := 1.
+
+        i := i - 1.
+        nargs := 0.
+        (tokens at: i) type == $( ifTrue:[ 
+            i := i - 1.
+        ] ifFalse:[
+            nargs := 1.
+            [ i > 0 and:[ nparens ~~ 0 ] ] whileTrue:[ 
+                (tokens at: i) type == $) ifTrue:[ 
+                    nparens := nparens + 1 
+                ] ifFalse:[ 
+                    (tokens at: i) type == $( ifTrue:[ 
+                        nparens := nparens - 1 
+                    ] ifFalse:[ 
+                        (((tokens at: i) type == $,) and:[nparens == 1]) ifTrue:[    
+                            nargs := nargs + 1.
+                        ]
+                    ].
+                ].
+                i := i - 1.
+            ].
+        ].
+        nparens ~~ 0 ifTrue:[ 
+            "/ Malformed input
+            ^ Type unknown
+        ].
+        (tokens at: i) type == #Identifier ifFalse:[ 
+            "/ Malformed input
+            ^ Type unknown
+        ].
+        name := (tokens at: i) value.
+        i > 0 ifTrue:[ 
+            (tokens at: i - 1) type == $. ifTrue:[ 
+                type := self guessTypeOfExpressionBefore: i - 1 in: tokens.
+            ] ifFalse:[ 
+                type := self guessTypeOfThis.
+            ].
+            ^ self guessTypeOfMethod: type of: type numArgs: nargs.
+        ].
+    ].
+    (tokens at: i) type == #Identifier ifTrue:[ 
+        "/ Either field or local
+        | name type |
+
+        name := (tokens at: i) value.
+        (i > 1 and:[ (tokens at: i - 1) type == $. ]) ifTrue:[ 
+            "/ Non-this field
+            type := self guessTypeOfExpressionBefore: i - 1 in: tokens.      
+            ^ self guessTypeOfField: name of: type.  
+        ] ifFalse:[ 
+            "/ This-field
+            ^ self guessTypeOfFieldOrLocal: name
+        ].
+    ].
+
+    ^ Type unknown    
+"/    ^ Type withClass: 
+"/        (context environment classNamed:#'JAVA::java::lang::Object')
+"/            ? (context environment classNamed:#'java/lang/Object')
+
+    "Created: / 17-05-2014 / 10:51:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfField: name of: type
+    ^ Type unknown
+
+    "Created: / 17-05-2014 / 10:47:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfFieldOrLocal: name
+    ^ Type unknown
+
+    "Created: / 17-05-2014 / 10:47:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfMethod: name of: type numArgs: nargs
+    | methods |
+
+    methods := Set new.
+    type classesDo:[:initialClass | 
+        | class |
+
+        class := initialClass.
+        [ class notNil and:[ class ~~ JavaObject  ] ] whileTrue:[
+            class selectorsAndMethodsDo:[:selector :method |
+                method isJavaMethod ifTrue:[ 
+                    (selector size > name size 
+                        and:[ method numJavaArgs = nargs
+                        and:[ (selector at: name size + 1) == $(
+                        and:[ (selector startsWith: name) ]]])
+                        ifTrue:[ methods add: method ].
+                    ].
+            ].
+        ].
+    ].
+
+    self halt.
+
+    "Created: / 15-05-2014 / 09:39:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+guessTypeOfThis
+    ^ class isNil 
+        ifTrue:[ Type unknown ]
+        ifFalse: [ Type withClass: class ]
+
+    "Created: / 17-05-2014 / 10:52:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 22-05-2014 / 17:34:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineSimple class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
+
+AbstractJavaCompletionEngineSimple initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractJavaCompletionEngineTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,184 @@
+"{ Encoding: utf8 }"
+
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+CompletionEngineTests subclass:#AbstractJavaCompletionEngineTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!AbstractJavaCompletionEngineTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractJavaCompletionEngineTests class methodsFor:'accessing'!
+
+resources
+    ^ Array with: JavaCompletionEngineEnvironmentResource
+
+    "Created: / 22-05-2014 / 17:18:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractJavaCompletionEngineTests class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == AbstractJavaCompletionEngineTests.
+! !
+
+!AbstractJavaCompletionEngineTests methodsFor:'tests - completion'!
+
+test_complete_catch_01a
+    "
+    Test catch completion
+    "
+
+    | java_io_IOException |
+
+    self complete:'try { 
+        do(something);
+    } catch ( IOE┃'.
+
+    java_io_IOException := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::io::IOException'  ]
+                            ifFalse:[ context environment classNamed: #'java/io/IOException'].
+
+    self assert: result notEmpty.
+    self assert: (result allSatisfy:[:each | each isSmallSenseClassPO ]).
+    self assert: (result contains:[:each | each klass == java_io_IOException ]).
+
+    "Created: / 07-08-2014 / 15:11:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_catch_01b
+    "
+    Test catch completion
+    "
+
+    | java_io_IOException |
+
+    self complete:'try { 
+        do(something);
+    } catch ( ┃'.
+
+    java_io_IOException := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::io::IOException'  ]
+                            ifFalse:[ context environment classNamed: #'java/io/IOException'].
+
+    self assert: result notEmpty.
+    self assert: (result allSatisfy:[:each | each isSmallSenseClassPO ]).
+    self assert: (result contains:[:each | each klass == java_io_IOException ]).
+
+    "Created: / 07-08-2014 / 16:02:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_catch_01c
+    "
+    Test catch completion
+    "
+
+    | java_io_IOException |
+
+    self complete:'try { 
+        do(something);
+    } catch ( java.io.IO┃'.
+
+    java_io_IOException := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::io::IOException'  ]
+                            ifFalse:[ context environment classNamed: #'java/io/IOException'].
+
+    self assert: result notEmpty.
+    self assert: (result allSatisfy:[:each | each isSmallSenseClassPO ]).
+    self assert: (result contains:[:each | each klass == java_io_IOException ]).
+
+    "Created: / 07-08-2014 / 16:07:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_catch_01d
+    "
+    Test catch completion
+    "
+
+    | java_io_IOException |
+
+    self complete:'try { 
+        do(something);
+    } catch ( java.io.┃'.
+
+    java_io_IOException := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::io::IOException'  ]
+                            ifFalse:[ context environment classNamed: #'java/io/IOException'].
+
+    self assert: result notEmpty.
+    self assert: (result allSatisfy:[:each | each isSmallSenseClassPO ]).
+    self assert: (result contains:[:each | each klass == java_io_IOException ]).
+
+    "Created: / 07-08-2014 / 16:08:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_catch_01e
+    "
+    Test catch completion
+    "
+
+    | java_io_IOException |
+
+    self complete:'try { 
+        do(something);
+    } catch ( jav┃'.
+
+    java_io_IOException := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::io::IOException'  ]
+                            ifFalse:[ context environment classNamed: #'java/io/IOException'].
+
+    self assert: result notEmpty.
+    self assert: (result allSatisfy:[:each | each isSmallSenseClassPO ]).
+    self assert: (result contains:[:each | each klass == java_io_IOException ]).
+
+    "Created: / 07-08-2014 / 16:20:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractListDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,927 @@
+"{ Encoding: utf8 }"
+
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractDIalog subclass:#AbstractListDialog
+	instanceVariableNames:'matchingObjectsView matchingObjectsMultiselect
+		matchingObjectsTree matchingObjectsSelectionHolder
+		matchingObjectsLabelHolder matchingObjectsUpdateJob
+		matchPatternHolder matchPatternView environmentHolder
+		filterHolder filter nextSearchStepVisibleHolder'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!AbstractListDialog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractListDialog class methodsFor:'interface specs-content'!
+
+contentPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::AbstractListDialog andSelector:#contentPaneSpec
+     SmallSense::AbstractListDialog new openInterface:#contentPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: contentPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Search...'
+         name: 'Search...'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 708 404)
+         menu: mainMenuSpec
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (VerticalPanelViewSpec
+             name: 'Content'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             horizontalLayout: fit
+             verticalLayout: topSpaceFit
+             component: 
+            (SpecCollection
+               collection: (
+                (ViewSpec
+                   name: 'Box1'
+                   component: 
+                  (SpecCollection
+                     collection: (
+                      (LabelSpec
+                         label: 'Enter name prefix or pattern (*):'
+                         name: 'PatternLabel'
+                         layout: (LayoutFrame 0 0 0 0 -100 1 0 1)
+                         translateLabel: true
+                         adjust: left
+                       )
+                      (UISubSpecification
+                         name: 'SubSpecification1'
+                         layout: (LayoutFrame -100 1 0 0 0 1 0 1)
+                         visibilityChannel: hasOptions
+                         minorKey: optionsShowHideRightAlignedPaneSpec
+                       )
+                      )
+                    
+                   )
+                   extent: (Point 708 30)
+                 )
+                (InputFieldSpec
+                   name: 'Pattern'
+                   model: matchPatternHolder
+                   immediateAccept: true
+                   acceptOnReturn: true
+                   acceptOnTab: true
+                   acceptOnPointerLeave: true
+                   entryCompletionBlock: matchPatternCompletionBlock
+                   extent: (Point 706 24)
+                   usePreferredHeight: true
+                   postBuildCallback: postBuildMatchPatternView:
+                 )
+                (ViewSpec
+                   name: 'Box2'
+                   component: 
+                  (SpecCollection
+                     collection: (
+                      (LabelSpec
+                         label: 'Matching items:'
+                         name: 'MatchingLabel'
+                         layout: (LayoutFrame 0 0 0 0 -25 1 0 1)
+                         translateLabel: true
+                         labelChannel: matchingObjectsLabelHolder
+                         adjust: left
+                       )
+                      (LabelSpec
+                         label: '->'
+                         name: 'Label1'
+                         layout: (LayoutFrame -25 1 0 0 0 1 0 1)
+                         visibilityChannel: nextSearchStepVisibleHolder
+                         translateLabel: true
+                         labelChannel: nextSearchStepLabel
+                       )
+                      )
+                    
+                   )
+                   extent: (Point 708 25)
+                 )
+                (HierarchicalListViewSpec
+                   name: 'HierarchicalListView1'
+                   model: matchingObjectsSelectionHolder
+                   hasHorizontalScrollBar: true
+                   hasVerticalScrollBar: true
+                   listModel: matchingObjectsTree
+                   multipleSelectOk: true
+                   useIndex: false
+                   highlightMode: line
+                   doubleClickSelector: doAcceptByDoubleClick
+                   selectConditionSelector: canSelectIndex:
+                   showLines: false
+                   showIndicators: false
+                   showLeftIndicators: false
+                   useDefaultIcons: false
+                   showRoot: false
+                   extent: (Point 708 303)
+                   postBuildCallback: postBuildMatchingObjectsView:
+                 )
+                )
+              
+             )
+           )
+          )
+        
+       )
+     )
+! !
+
+!AbstractListDialog class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::AbstractListDialog.
+! !
+
+!AbstractListDialog methodsFor:'accessing'!
+
+environment
+    ^ self environmentHolder value
+
+    "Created: / 22-04-2014 / 10:45:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+environment: aJavaClassEnvironment
+    ^self environmentHolder value: aJavaClassEnvironment
+
+    "Created: / 22-04-2014 / 10:46:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+filter
+    ^self filterHolder value.
+
+    "Created: / 11-03-2013 / 17:37:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+filter: aBlock
+    self filterHolder value: aBlock
+
+    "Created: / 10-05-2014 / 00:41:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsSelection
+    ^ self matchingObjectsSelectionHolder value
+
+    "Created: / 10-05-2014 / 00:47:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsSelection: selection
+    self matchingObjectsSelectionHolder value: selection withoutNotifying:self.
+    self updateAcceptEnabled.
+
+    "Created: / 02-05-2014 / 12:26:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 13:59:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+multiselect
+    ^ matchingObjectsMultiselect
+
+    "Created: / 10-05-2014 / 11:22:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+multiselect: aBoolean
+    matchingObjectsMultiselect := aBoolean.
+    matchingObjectsView notNil ifTrue:[
+        matchingObjectsView multipleSelectOk: aBoolean
+    ].
+
+    "Created: / 10-05-2014 / 11:22:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+pattern
+    ^self matchPatternHolder value.
+
+    "Created: / 11-03-2013 / 14:39:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+pattern: aString
+    ^self matchPatternHolder value: aString
+
+    "Created: / 11-03-2013 / 15:21:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selection: selection
+    | matchingObjectsSelection |
+
+    matchingObjectsMultiselect ifTrue:[
+        matchingObjectsSelection := selection collect:[ :each | matchingObjectsTree root recursiveDetect: [ :po | (po isKindOf: PO) and:[ po subject = each ] ] ].
+        matchingObjectsSelection := matchingObjectsSelection reject:[:each | each isNil ].
+    ] ifFalse:[
+        matchingObjectsSelection := matchingObjectsTree root recursiveDetect: [ :po | (po isKindOf: PO) and:[ po subject = selection ] ]
+    ].
+    self matchingObjectsSelection: matchingObjectsSelection.
+
+    "Created: / 10-05-2014 / 00:50:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-01-2015 / 10:55:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+title
+    ^ self titleHolder value.
+
+    "Created: / 05-05-2014 / 23:35:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+title: aString
+    | title |
+
+
+    title := aString.
+    (title includes: Character cr) ifTrue:[
+        title := title upTo:Character cr.
+    ].
+    self titleHolder value: title
+
+    "Created: / 05-05-2014 / 23:36:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-05-2014 / 01:22:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'accessing - private'!
+
+matchingObjectForString: aString
+    "Creates a new object from given string. Called only when
+     #canCreateMatchingObjectFromString: returns true"
+
+    (self canCreateMatchingObjectFromString:aString) ifFalse:[
+        self shouldNeverBeSent
+    ] ifTrue:[
+        self subclassResponsibility
+    ]
+
+    "Created: / 23-06-2014 / 15:20:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'accessing-defaults'!
+
+defaultTitle
+    ^ (resources string: 'Search...')
+
+    "Created: / 05-05-2014 / 23:39:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'aspects'!
+
+environmentHolder
+    "return/create the 'registryHolder' value holder (automatically generated)"
+
+    environmentHolder isNil ifTrue:[
+        environmentHolder := Smalltalk asValue.
+        environmentHolder addDependent:self.
+    ].
+    ^ environmentHolder
+
+    "Created: / 22-04-2014 / 10:45:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-04-2014 / 00:04:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+environmentHolder:something
+    "set the 'registryHolder' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    environmentHolder notNil ifTrue:[
+        oldValue := environmentHolder value.
+        environmentHolder removeDependent:self.
+    ].
+    environmentHolder := something.
+    environmentHolder notNil ifTrue:[
+        environmentHolder addDependent:self.
+    ].
+    newValue := environmentHolder value.
+    oldValue ~~ newValue ifTrue:[
+        self update:#value with:newValue from:environmentHolder.
+    ].
+
+    "Created: / 22-04-2014 / 10:45:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+filterHolder
+    "return/create the 'filterHolder' value holder (automatically generated)"
+
+    filterHolder isNil ifTrue:[
+        filterHolder := ValueHolder new.
+        filterHolder addDependent:self.
+    ].
+    ^ filterHolder
+!
+
+filterHolder:something
+    "set the 'filterHolder' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    filterHolder notNil ifTrue:[
+        oldValue := filterHolder value.
+        filterHolder removeDependent:self.
+    ].
+    filterHolder := something.
+    filterHolder notNil ifTrue:[
+        filterHolder addDependent:self.
+    ].
+    newValue := filterHolder value.
+    oldValue ~~ newValue ifTrue:[
+        self update:#value with:newValue from:filterHolder.
+    ].
+!
+
+matchPatternCompletionBlock
+    ^ [ :contents :field |
+        | completion |
+        (contents notEmptyOrNil and:[ matchingObjectsUpdateJob running not]) ifTrue:[
+            field topView withCursor:(Cursor questionMark) do:[
+                completion := self matchPatternCompletionFor: contents
+            ].
+        ].
+        completion notNil ifTrue:[
+            self enqueueDelayedAction:[  
+                matchPatternHolder value: completion first withoutNotifying: self.   
+                "/ field contents: completion first.
+            ].
+            completion second size == 1 ifTrue:[
+                matchingObjectsMultiselect ifTrue:[
+                    self matchingObjectsSelection: completion second asArray
+                ] ifFalse:[
+                    self matchingObjectsSelection: completion second anElement.
+                ].
+            ].
+        ] ifFalse:[
+            matchingObjectsView flash.
+        ]
+    ]
+
+    "Created: / 28-04-2014 / 22:30:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-01-2015 / 11:07:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchPatternHolder
+    <resource: #uiAspect>
+
+    matchPatternHolder isNil ifTrue:[
+        matchPatternHolder := ValueHolder new.
+    ].
+    ^ matchPatternHolder.
+
+    "Modified: / 25-11-2014 / 13:52:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsLabelHolder
+    <resource: #uiAspect>
+
+    "automatically generated by UIPainter ..."
+
+    "*** the code below creates a default model when invoked."
+    "*** (which may not be the one you wanted)"
+    "*** Please change as required and accept it in the browser."
+    "*** (and replace this comment by something more useful ;-)"
+
+    matchingObjectsLabelHolder isNil ifTrue:[
+        matchingObjectsLabelHolder := ValueHolder with:(resources string:'Matching items:').
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/       matchingLabelHolder addDependent:self.
+"/       matchingLabelHolder onChangeSend:#matchingLabelHolderChanged to:self.
+    ].
+    ^ matchingObjectsLabelHolder.
+
+    "Created: / 28-04-2014 / 22:29:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsSelectionHolder
+    "return/create the 'matchingClassesSelectionHolder' value holder (automatically generated)"
+
+    matchingObjectsSelectionHolder isNil ifTrue:[
+        matchingObjectsSelectionHolder := ValueHolder new.
+        matchingObjectsSelectionHolder addDependent:self.
+    ].
+    ^ matchingObjectsSelectionHolder
+
+    "Modified: / 08-03-2013 / 14:05:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsSelectionHolder:something
+    "set the 'matchingClassesSelectionHolder' value holder (automatically generated)"
+
+    matchingObjectsSelectionHolder := something.
+!
+
+matchingObjectsTree
+    <resource: #uiAspect>
+    matchingObjectsTree isNil ifTrue:[
+        matchingObjectsTree := HierarchicalList new.
+        matchingObjectsTree showRoot:false.
+        matchingObjectsTree root:(HierarchicalItem new).
+        matchingObjectsTree application:self.
+        self updateNoResults:matchingObjectsTree root.
+    ].
+    ^ matchingObjectsTree.
+
+    "Created: / 08-03-2013 / 15:40:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 27-04-2014 / 23:41:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+nextSearchStepLabel
+    ^ OperatingSystem isUNIXlike ifTrue:[ '→' ] ifFalse:[ '->' ].
+
+    "Created: / 23-01-2015 / 21:59:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+nextSearchStepVisibleHolder
+    <resource: #uiAspect>
+
+    nextSearchStepVisibleHolder isNil ifTrue:[
+        nextSearchStepVisibleHolder := false asValue.
+    ].
+    ^ nextSearchStepVisibleHolder.
+
+    "Modified: / 23-01-2015 / 22:00:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'aspects-queries'!
+
+hasFilter
+    ^self filterHolder value notNil
+
+    "Created: / 08-03-2013 / 15:43:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-03-2013 / 17:34:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'change & update'!
+
+enqueueDelayedUpdateMatchingObjectPOs: matchingPOsArg
+    self enqueueMessage: #delayedUpdateMatchingObjectPOs: for: self arguments: (Array with: matchingPOsArg)
+
+    "Created: / 21-02-2015 / 08:57:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+update:something with:aParameter from:changedObject
+    "Invoked when an object that I depend upon sends a change notification."
+
+    changedObject == matchPatternHolder ifTrue:[
+        matchingObjectsUpdateJob restart.
+        self updateAcceptEnabled.
+        ^ self.
+    ].
+    changedObject == matchingObjectsSelectionHolder ifTrue:[
+        self updateMatchPatternHolderFromSelection.
+        self updateAcceptEnabled.
+        ^ self.
+    ].
+    changedObject == accept ifTrue:[
+        accept value ifTrue:[
+            self updateAcceptedValue.
+        ].
+        ^ self.
+    ].
+    changedObject == filterHolder ifTrue:[
+        (filter notNil and:[filter isBlock not and:[(filter isKindOf: MessageSend) not]]) ifTrue:[filter removeDependent: self].
+        filter := filterHolder value.
+        (filter notNil and:[filter isBlock not and:[(filter isKindOf: MessageSend) not]]) ifTrue:[filter addDependent: self].
+        "/ Only do this after window is opened....
+        (self builder notNil and:[ self builder window notNil  ]) ifTrue:[
+            matchingObjectsUpdateJob restart.
+        ].
+         ^ self.
+    ]    .
+    changedObject == filter ifTrue:[
+        matchingObjectsUpdateJob restart.
+    ].
+    super update:something with:aParameter from:changedObject
+
+    "Modified: / 21-02-2015 / 08:26:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateAcceptEnabled
+    self acceptEnabledHolder value:
+        (matchingObjectsSelectionHolder value notEmptyOrNil
+            or:[ self canCreateMatchingObjectFromString:self matchPatternHolder value ])
+
+    "Created: / 08-03-2013 / 14:06:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-01-2015 / 11:06:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateAcceptedValue
+    "Dialog has been accepted (OK pressed). Update accepted value"
+
+    | matchingObjectsSelection |
+
+    matchingObjectsSelection := matchingObjectsSelectionHolder value.
+    (matchingObjectsTree includes: matchingObjectsSelection) ifFalse:[ 
+        matchingObjectsSelection := nil.
+    ].
+    matchingObjectsSelection isEmptyOrNil ifTrue:[
+        (self canCreateMatchingObjectFromString:matchPatternView contents) ifTrue:[
+            acceptedValue := self matchingObjectForString: matchPatternView contents.
+            matchingObjectsMultiselect ifTrue:[ 
+                acceptedValue := Array with: acceptedValue
+            ].
+        ].
+    ] ifFalse:[
+        acceptedValue := matchingObjectsMultiselect
+            ifTrue:[ matchingObjectsSelection collect:[:e|e subject] ]
+            ifFalse:[ matchingObjectsSelection subject ]
+    ].
+
+    "Created: / 19-06-2014 / 11:57:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-01-2015 / 06:41:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateMatchPatternHolderFromSelection
+    | pattern selection |
+
+    "/ Do not update pattern if it contains match characters
+    pattern := matchPatternHolder value.
+    pattern notEmptyOrNil ifTrue:[
+        (pattern first isSeparator or:[pattern includesAny: '*?']) ifTrue:[
+            ^self
+        ]
+    ].
+    selection := matchingObjectsSelectionHolder value.
+    selection isSequenceable ifTrue:[
+        selection size == 1 ifTrue:[
+            selection := selection anElement.
+        ] ifFalse:[
+            selection := nil.
+        ]
+    ].
+    selection notNil ifTrue:[
+        matchPatternHolder value: selection label withoutNotifying: self.
+        matchPatternView notNil ifTrue:[
+            matchPatternView selectAll.
+        ]
+    ].
+
+    "Created: / 06-10-2014 / 23:59:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 13:23:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateMatchingLabelToNormal
+    self matchingObjectsLabelHolder value: (resources string: 'Matching items:').
+
+    "Created: / 18-03-2013 / 14:02:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-04-2014 / 22:29:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateMatchingLabelToRecentSearches
+    self matchingObjectsLabelHolder value: (resources string: 'Recently searched:').
+
+    "Created: / 30-04-2014 / 11:47:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateMatchingLabelToSearching
+    self matchingObjectsLabelHolder value: (resources string: 'Searching...').
+
+    "Created: / 18-03-2013 / 14:01:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-04-2014 / 22:29:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateNoResults: root
+    | items |
+
+    items := (Array with: ((HierarchicalItemWithLabel new parent: root; label:((resources string:'No search results...') asText colorizeAllWith: Color gray)))).
+    self enqueueDelayedUpdateMatchingObjectPOs: items.
+
+    "Created: / 11-03-2013 / 14:33:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 08:58:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'change & update-background'!
+
+updateMatching
+    | pattern pos |
+
+    self assert: [ Processor activeProcess == matchingObjectsUpdateJob thread ] message: 'This method can be called only from background update job'.
+
+    self matchPatternHolder value notEmptyOrNil ifTrue:[
+        pattern := StringPattern fromString: self matchPatternHolder value.
+        pos := self matchingObjectPOsForPattern: pattern.
+        self enqueueDelayedUpdateMatchingObjectPOs: pos.
+        self updateMatchingLabelToNormal
+    ] ifFalse:[
+        self updateMatchingIgnorePattern
+    ].
+
+    "Created: / 12-12-2014 / 23:38:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 08:57:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateMatchingIgnorePattern
+
+    self assert: [ Processor activeProcess == matchingObjectsUpdateJob thread ] message: 'This method can be called only from background update job'.
+
+    self enqueueDelayedUpdateMatchingObjectPOs: (self matchingObjectPOsForPattern: nil)
+
+    "Created: / 12-12-2014 / 23:39:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 08:58:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'change & update-delayed'!
+
+delayedUpdateMatchingObjectPOs: matchingPOsArg
+    | rootPO matchPatternString  |
+
+    rootPO := self matchingObjectsTree root.
+    rootPO
+        children:matchingPOsArg;
+        expand.
+    matchPatternString := self matchPatternHolder value.
+    matchPatternString isEmptyOrNil ifTrue:[ 
+        ^ self.
+    ].
+    matchingPOsArg size == 1 ifTrue:[
+        matchingObjectsMultiselect ifTrue:[
+            self matchingObjectsSelection: matchingPOsArg
+        ] ifFalse:[
+            self matchingObjectsSelection: matchingPOsArg anElement
+        ]
+    ].
+
+    "Created: / 12-12-2014 / 23:32:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'event processing'!
+
+handlesKeyPress: key inView: view
+    view == matchingObjectsView ifTrue:[ 
+        ^ key == #CursorLeft or:[ key == #CursorRight ]
+    ].
+    ^ false
+
+    "Created: / 23-01-2015 / 22:35:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPress: key x:x y:y view: view
+    view == matchingObjectsView ifTrue:[ 
+        key == #CursorRight ifTrue:[ 
+            ^ self keyPressCursorRightInMatchingObjectsView.
+        ].
+        key == #CursorLeft ifTrue:[ 
+            ^ self keyPressCursorLeftInMatchingObjectsView.
+        ].
+    ].
+    ^ false
+
+    "Created: / 23-01-2015 / 22:36:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressCursorDownInPatternView
+
+    matchingObjectsView hasSelection ifFalse:[
+        matchingObjectsView selectFirst.
+    ] ifTrue:[
+        matchingObjectsView selectNext.
+    ].
+    matchingObjectsView windowGroup focusView:matchingObjectsView byTab:true.
+
+    "Created: / 22-04-2014 / 11:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressCursorLeftInMatchingObjectsView
+    matchingObjectsView windowGroup focusView:matchPatternView byTab:true.
+    matchPatternView keyPress: #CursorLeft x: 0 y: 0.
+    ^ true
+
+    "Created: / 23-01-2015 / 22:41:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressCursorRightInMatchingObjectsView
+    matchingObjectsView windowGroup focusView:matchPatternView byTab:true.
+    matchPatternView keyPress: #CursorRight x: 0 y: 0.
+    ^ true
+
+    "Created: / 23-01-2015 / 22:41:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'events'!
+
+closeCancel
+    "cancel was pressed. close the dialog"
+
+    accept setValue: nil.
+    ^ super closeCancel.
+
+    "Created: / 28-04-2014 / 23:56:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'forced actions'!
+
+doAcceptByDoubleClick
+    self acceptEnabledHolder value ifTrue:[
+        self doAccept
+    ].
+
+    "Created: / 08-03-2013 / 14:20:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+doAcceptByReturnKey
+    self acceptEnabledHolder value ifTrue:[
+        super doAcceptByReturnKey
+    ].
+
+    "Created: / 08-03-2013 / 14:14:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'hooks'!
+
+commonPostBuild
+
+    matchPatternHolder addDependent:self.
+    matchPatternView selectAll.
+
+    matchingObjectsUpdateJob restart:[ self updateMatchingIgnorePattern].
+    self updateAcceptEnabled.
+    self updateMatchPatternHolderFromSelection.
+    super commonPostBuild
+
+    "Created: / 25-11-2014 / 13:23:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 17:49:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+commonPreOpen
+    | selection |
+    selection := self matchingObjectsSelection.
+    selection notEmptyOrNil ifTrue:[ 
+        matchingObjectsView makeSelectionVisible
+    ].
+    super commonPreOpen
+
+    "Created: / 09-01-2015 / 11:09:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+postBuildMatchPatternView:aView
+    matchPatternView := aView scrolledView.
+"/    matchPatternView delegate: self.
+    matchPatternView onKey:#CursorDown leaveWith:[ self keyPressCursorDownInPatternView ]
+
+    "Created: / 28-04-2014 / 22:27:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+postBuildMatchingObjectsView:aView
+    matchingObjectsView := aView scrolledView.
+    matchingObjectsView delegate: self.
+    matchingObjectsView multipleSelectOk: matchingObjectsMultiselect
+
+    "Created: / 22-04-2014 / 13:21:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-05-2014 / 11:23:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    super initialize.
+
+    "/ please change as required (and remove this comment)
+    "/ acceptEnabledHolder := nil.
+    "/ allClassesHolder := nil.
+    "/ matchingClassesList := nil.
+    "/ matchingClassesHolder := nil.
+    "/ matchPatternHolder := nil.
+    "/ matchingUpdateJob := nil.
+
+    self accept addDependent: self.
+    self matchingObjectsTree. "/force its initialization
+    matchingObjectsUpdateJob := BackgroundJob named: 'SmallSense search dialog updater' on:[self updateMatching].
+    matchingObjectsMultiselect := false.
+
+    "Modified: / 13-12-2014 / 08:46:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'queries'!
+
+canCreateMatchingObjectFromString:string
+    "Return true, a new object can be created with given string value"
+
+    ^ false
+
+    "Created: / 23-06-2014 / 15:14:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canSelect: selection
+    "raise an error: must be redefined in concrete subclass(es)"
+
+    ^ self subclassResponsibility
+
+    "Modified (format): / 28-04-2014 / 00:11:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canSelectIndex: selectionIndex
+    (selectionIndex between: 1 and: matchingObjectsTree size) ifTrue:[
+        ^ self canSelect: (matchingObjectsTree at: selectionIndex)
+    ].
+    ^ false
+
+    "Created: / 02-05-2014 / 23:52:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hasOptions
+    ^ false
+
+    "Created: / 09-05-2014 / 23:58:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog methodsFor:'searching'!
+
+matchPatternCompletionFor: contents
+   | pattern |
+
+   pattern := StringPattern fromString: contents.
+   (pattern isKindOf: StringPattern::StartsWith) ifFalse:[ ^ nil ].
+   ^ self matchPatternCompletionFor: contents pattern: pattern
+
+    "Created: / 02-05-2014 / 10:50:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchPatternCompletionFor: contents pattern: pattern
+    | completionPOs completionPOLabels completion matchingPOs |
+
+    completionPOs := self matchingObjectsTree root
+                        recursiveSelect:[:item | (self canSelect: item) and:[ pattern match: item label relax: 1 ] ].
+    completionPOLabels := completionPOs collect:[ :each | each label ].
+    completion := completionPOLabels longestCommonPrefix.
+    completion isEmptyOrNil ifTrue:[ ^ nil ].
+    completion = contents ifTrue:[ ^ nil ].
+    matchingPOs := OrderedCollection new.
+    completionPOs with: completionPOLabels do:[:po :poLabel |
+        poLabel = completion ifTrue:[
+            matchingPOs add: po.
+        ].
+    ].
+    ^ Array with: completion with: matchingPOs.
+
+    "Created: / 02-05-2014 / 10:58:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-10-2014 / 10:12:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectPOsForPattern: pattern
+    ^ self subclassResponsibility
+
+    "Created: / 13-12-2014 / 08:33:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractListDialog class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractSearchDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,194 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractListDialog subclass:#AbstractSearchDialog
+	instanceVariableNames:'recentlySearchedPatterns recentlySearchedObjectPOs processor'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+AbstractSearchDialog class instanceVariableNames:'recentlySearchedPatterns'
+
+"
+ The following class instance variables are inherited by this class:
+
+	SmallSense::AbstractListDialog - 
+	SmallSense::AbstractDIalog - 
+	SimpleDialog - 
+	ApplicationModel - ClassResources
+	Model - 
+	Object - 
+"
+!
+
+!AbstractSearchDialog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractSearchDialog class methodsFor:'accessing'!
+
+recentlySearchedPatterns
+    recentlySearchedPatterns isNil ifTrue:[
+        recentlySearchedPatterns := OrderedSet new.
+    ].
+    ^ recentlySearchedPatterns
+
+    "Created: / 28-04-2014 / 23:13:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::AbstractSearchDialog.
+! !
+
+!AbstractSearchDialog class methodsFor:'remembering'!
+
+rememberSearchPattern: pattern
+    self recentlySearchedPatterns add: pattern
+
+    "Created: / 11-01-2015 / 06:16:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog methodsFor:'accessing'!
+
+processor
+    ^ processor
+!
+
+processor:aAbstractSearchProcessor
+    processor := aAbstractSearchProcessor.
+! !
+
+!AbstractSearchDialog methodsFor:'accessing - private'!
+
+matchingObjectForString:aString
+    "Creates a new object from given string. Called only when
+     #canCreateMatchingObjectFromString: returns true"
+
+    ^ self shouldNotImplement
+
+    "Created: / 10-01-2015 / 10:24:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+    "Invoked when an object that I depend upon sends a change notification."
+
+    changedObject == accept ifTrue:[
+        accept value ifTrue:[
+            self updateAcceptedValue.
+            self class rememberSearchPattern: self pattern.
+            matchingObjectsMultiselect ifTrue:[
+                self processor rememberSearchObjectPOs: matchingObjectsSelectionHolder value.
+            ] ifFalse:[
+                self processor rememberSearchObjectPO: matchingObjectsSelectionHolder value.
+            ].
+        ].
+        ^ self.
+    ].  
+    super update:something with:aParameter from:changedObject
+
+    "Created: / 08-12-2014 / 02:36:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-01-2015 / 06:18:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog methodsFor:'change & update-background'!
+
+updateMatchingIgnorePattern
+
+    "/ Show recent searches rather than all items (there may be a lot...)
+    self enqueueDelayedUpdateMatchingObjectPOs: processor recentlySearchedObjectPOs.
+    self updateMatchingLabelToRecentSearches
+
+    "Created: / 12-12-2014 / 23:39:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 08:58:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog methodsFor:'hooks'!
+
+commonPostBuild
+"/    self updateMatching.
+"/    recentlySearchedPatterns notEmptyOrNil ifTrue:[
+"/        matchPatternView contents: self recentlySearchedPatterns last.
+"/        matchPatternView selectAll.
+"/    ].
+    recentlySearchedObjectPOs notEmptyOrNil ifTrue:[
+        self enqueueDelayedUpdateMatchingObjectPOs: recentlySearchedObjectPOs asArray reverse.
+        self updateMatchingLabelToRecentSearches.
+    ].
+    super commonPostBuild
+
+    "Created: / 25-11-2014 / 13:23:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 08:58:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog methodsFor:'queries'!
+
+canSelect: selection
+    "raise an error: must be redefined in concrete subclass(es)"
+
+    ^ (selection isKindOf: PO) and:[ selection isSmallSensePluggablePO not or:[ selection subject ~~ processor ] ]
+
+    "Created: / 10-01-2015 / 10:23:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog methodsFor:'searching'!
+
+matchingObjectPOsForPattern: pattern
+    ^ processor matchingObjectPOsForPattern: pattern filter: filter inEnvironment: self environment
+
+    "Created: / 13-12-2014 / 08:33:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchDialog class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractSearchProcessor.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,178 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#AbstractSearchProcessor
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+AbstractSearchProcessor class instanceVariableNames:'recentlySearchedObjectPOs'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+!AbstractSearchProcessor class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractSearchProcessor class methodsFor:'accessing'!
+
+recentlySearchedObjectPOs
+    recentlySearchedObjectPOs isNil ifTrue:[
+        recentlySearchedObjectPOs := OrderedSet new.
+    ].
+    ^ recentlySearchedObjectPOs
+
+    "Created: / 13-12-2014 / 08:23:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchProcessor class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::AbstractSearchProcessor.
+! !
+
+!AbstractSearchProcessor class methodsFor:'remembering'!
+
+rememberSearchObjectPO: aPO
+    self recentlySearchedObjectPOs add: aPO
+
+    "Created: / 11-01-2015 / 06:19:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchProcessor methodsFor:'accessing'!
+
+canDoNextStepFor: aPO
+    "Return true if navigation can take a next step for given PO
+     (i.e., if user can 'dive in'), false otherwise.
+     To be overriden by subclasses to avoid excessive processor creation."
+
+    ^ (self processorForNextStepFor: aPO) notNil.
+
+    "Created: / 23-01-2015 / 22:16:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+processorForNextStepFor: aPO
+    "Return a processor for next navigation step for given PO.
+     If nil is returned, then there's no next step (i.e.,
+     a user connot 'dive in')"
+
+    ^ nil
+
+    "Created: / 23-01-2015 / 22:04:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+recentlySearchedObjectPOs
+    ^ self class recentlySearchedObjectPOs asArray reversed
+
+    "Created: / 11-01-2015 / 06:21:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchProcessor methodsFor:'accessing - presentation'!
+
+label
+    "Return a label for this processor. This one is used as section label
+     in Spotter"
+
+    ^ self subclassResponsibility
+
+    "Created: / 10-01-2015 / 06:40:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchProcessor methodsFor:'remembering'!
+
+rememberSearchObjectPO: po
+    self class rememberSearchObjectPO: po
+
+    "Created: / 11-01-2015 / 06:19:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+rememberSearchObjectPOs: pos
+    pos do:[:po | self rememberSearchObjectPO: po ]
+
+    "Created: / 11-01-2015 / 06:19:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSearchProcessor methodsFor:'searching'!
+
+matchingObjectPOsFor: objects
+
+    self subclassResponsibility.
+
+    "Created: / 30-04-2014 / 09:46:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectPOsForPattern:pattern filter: filter inEnvironment:environment
+    ^ self matchingObjectPOsFor: 
+        (self matchingObjectsForPattern: pattern filter: filter inEnvironment: environment).
+
+    "Created: / 12-12-2014 / 23:31:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsForPattern:pattern filter: filter inEnvironment:environment
+    | objects |
+
+    objects := self matchingObjectsForPattern:pattern filter: filter inEnvironment:environment relax: 1.
+    objects notEmptyOrNil ifTrue:[ ^ objects ].
+
+    objects := self matchingObjectsForPattern:pattern filter: filter inEnvironment:environment relax: 2.
+    objects notEmptyOrNil ifTrue:[ ^ objects ].
+
+    objects := self matchingObjectsForPattern:pattern filter: filter inEnvironment:environment relax: 3.
+    ^ objects
+
+    "Created: / 12-12-2014 / 21:23:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsForPattern:pattern filter: filter inEnvironment:environment relax: level
+    self subclassResponsibility
+
+    "Created: / 12-12-2014 / 21:22:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractSelectDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,89 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractListDialog subclass:#AbstractSelectDialog
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!AbstractSelectDialog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractSelectDialog class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::AbstractSelectDialog.
+! !
+
+!AbstractSelectDialog methodsFor:'accessing-defaults'!
+
+defaultTitle
+    ^ (resources string: 'Select...')
+
+    "Created: / 13-12-2014 / 12:57:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AbstractSelectDialog methodsFor:'searching'!
+
+matchingObjectPOsForPattern: pattern
+    | pos |
+
+    1 to: 3 do:[:i |
+        pos := self matchingObjectPOsForPattern: pattern relax: i.
+        pos notEmptyOrNil ifTrue:[ ^ pos ]
+    ].
+
+    "Created: / 13-12-2014 / 08:39:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectPOsForPattern: pattern relax: relax
+    self subclassResponsibility
+
+    "Created: / 13-12-2014 / 08:40:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__AbstractTestCase.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,101 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#AbstractTestCase
+	instanceVariableNames:'preferences'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!AbstractTestCase class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!AbstractTestCase class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::AbstractTestCase.
+! !
+
+!AbstractTestCase methodsFor:'running'!
+
+setUp
+    | keysToRemove |
+    preferences := Dictionary new.
+    keysToRemove := Set new.
+    UserPreferences current keysAndValuesDo:[ :key :value |
+        (key startsWith: 'smallSense') ifTrue:[ 
+            preferences at: key put: value.
+            keysToRemove add: key.
+        ].
+    ].
+    keysToRemove do:[:key | 
+        UserPreferences current removeKey: key.
+    ].
+    UserPreferences current smallSenseEnabled: true.
+
+    "Modified: / 11-08-2014 / 14:25:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+tearDown
+    | keysToRemove |
+
+    keysToRemove := Set new.
+    UserPreferences current keysAndValuesDo:[ :key :value |
+        (key startsWith: 'smallSense') ifTrue:[ 
+            keysToRemove add: key.
+        ].
+    ].
+    keysToRemove do:[:key | 
+        UserPreferences current removeKey: key.
+    ].
+    preferences keysAndValuesDo:[ :key :value |
+        UserPreferences current at: key put: value.
+    ].
+
+    "Created: / 11-08-2014 / 14:24:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__BaseTestClass.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,94 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#BaseTestClass
+	instanceVariableNames:'u v'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests-Obsolete'
+!
+
+!BaseTestClass class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!BaseTestClass methodsFor:'generate'!
+
+doForSource:src 
+    |parser|
+
+    parser := SmallSenseParser new.
+    parser 
+        parseMethod:'gen' , src
+        in:self class
+        ignoreErrors:false
+        ignoreWarnings:false.
+    ^ parser.
+
+    "Created: / 16-03-2011 / 12:27:38 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 17:45:23 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+processMethod: aCompiledMethod
+        "Fail by default. Needs to be overridden by subclasses to trigger the base testing backbone."
+
+        | collector |
+        collector := TypeCollector onClass: self class.
+        collector currentExtractedMethod: aCompiledMethod.
+        TypeCollector new newExtractor
+                extractInterfacesFrom: aCompiledMethod source class:aCompiledMethod mclass
+                addTo: collector.
+        ^collector
+
+    "Created: / 17-03-2011 / 16:56:07 / Jakub <zelenja7@fel.cvut.cz>"
+! !
+
+!BaseTestClass class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ClassInfo.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,162 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Info subclass:#ClassInfo
+	instanceVariableNames:'className methods instvars seqno'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types-Info'
+!
+
+!ClassInfo class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ClassInfo class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!ClassInfo methodsFor:'accessing'!
+
+className
+    ^ className
+!
+
+infoForInstvar: ivarName
+
+    ^instvars at: ivarName ifAbsentPut:[
+        Type default.
+    ]
+
+    "Created: / 27-11-2011 / 16:44:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+infoForInstvarOrNil: ivarName
+
+    ^instvars at: ivarName ifAbsent: nil
+
+    "Created: / 27-11-2011 / 17:15:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+infoForSelector: selector
+
+    ^methods at: selector ifAbsentPut:[
+        MethodInfo new setManager: manager classInfo: self selector: selector.
+
+    ]
+
+    "Created: / 27-11-2011 / 16:26:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+infoForSelectorOrNil: selector
+
+    ^methods at: selector ifAbsent:nil
+
+    "Created: / 27-11-2011 / 17:15:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+seqno
+    ^ seqno
+!
+
+seqno:anInteger
+    seqno := anInteger.
+!
+
+superclassInfo
+
+    | nm meta cls |
+
+    (className endsWith:' class') ifTrue:[
+        nm := (className copyTo: className size - 6) asSymbol.
+        meta := true.
+    ] ifFalse:[
+        nm := className asSymbol.
+        meta := false.
+    ].
+    cls := Smalltalk at: nm.
+    cls isNil ifTrue:[ ^ nil ].
+    meta ifTrue:[cls := cls theMetaclass].
+
+    ^ manager infoForClass: cls superclass
+
+    "Modified: / 29-11-2011 / 16:02:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassInfo methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    "/ superclassInfo := nil.
+    "/ className := nil.
+    methods := Dictionary new.
+    instvars := Dictionary new.
+
+    "/ super initialize.   -- commented since inherited method does nothing
+
+    "Modified: / 27-11-2011 / 16:53:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setManager: mgr className: nm
+
+    manager := mgr.
+    className := nm
+
+    "Created: / 29-11-2011 / 15:57:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassInfo class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ClassPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,231 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#ClassPO
+	instanceVariableNames:'showPrefix klass icon'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!ClassPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ClassPO methodsFor:'accessing'!
+
+hint
+    | namespace |
+
+    namespace := nil.
+    showPrefix ifFalse:[
+        namespace := klass isJavaClass
+                        ifTrue:[klass javaPackage]
+                        ifFalse:[ | ns | ns := klass nameSpace. [ ns isNameSpace ] whileFalse:[ ns := ns nameSpace ]. ns name].
+        (namespace notNil and:[namespace ~~ #Smalltalk]) ifTrue:[
+            ^ 'in ', namespace.
+        ].
+    ].
+    ^ nil
+
+    "Created: / 20-05-2014 / 12:21:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-07-2014 / 17:31:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+icon
+
+    icon ifNil:[icon := SystemBrowser iconForClass: klass].
+    ^icon
+
+    "Created: / 06-04-2011 / 23:36:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+klass
+    ^ klass
+
+    "Created: / 25-08-2013 / 13:07:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+klass: aClass
+    ^ klass := aClass
+
+    "Created: / 25-08-2013 / 13:07:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 10:05:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    label isNil ifTrue:[
+        showPrefix ifTrue:[
+            label := klass name.
+            (context notNil and:[klass isJavaClass]) ifTrue:[
+                | lang |
+
+                lang := context language.
+                (lang notNil and:[lang isJava]) ifTrue:[
+                    label := klass javaName
+                ] ifFalse:[
+                    (lang notNil and:[lang isSmalltalk]) ifTrue:[
+                       label := 'JAVA ' , (klass  binaryName copyReplaceAll: $/ with: Character space)
+                     ] ifFalse:[ 
+                        label := klass nameWithoutNameSpacePrefix.
+                     ].
+                ]
+            ].
+        ] ifFalse:[
+            label := klass nameWithoutNameSpacePrefix.
+        ].
+    ].
+
+    ^label
+
+    "Created: / 20-05-2014 / 11:29:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 16:19:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showPrefix
+    ^ showPrefix
+!
+
+showPrefix:aBoolean
+    showPrefix := aBoolean.
+!
+
+stringAlreadyWritten
+    "Answers a string already written in the textview"
+
+    klass isJavaClass ifTrue:[
+        context language isSmalltalk ifTrue:[
+            | rec |
+
+            rec := context node .
+            [ rec isUnaryMessage ] whileTrue:[
+                rec := rec receiver.
+            ].
+            (rec isVariableNode and:['JAVA' startsWith: rec name]) ifTrue:[
+                ^ context textView contents string copyFrom: rec startPosition to: context node endPosition
+            ].
+        ] ifFalse:[
+        context language isJavaLike ifTrue:[
+             ^ context wordBeforeCursorConsisitingOfCharactersMatching:[:c | c isAlphaNumeric or:['$_.' includes: c] ]
+        ]].
+    ].
+    ^ super stringAlreadyWritten
+
+    "Created: / 20-10-2013 / 02:46:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 27-03-2015 / 17:15:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage: language
+    ^ (klass isJavaClass and:[language isSmalltalk]) ifTrue:[
+	'JAVA ', (klass binaryName copyReplaceAll: $/ with: Character space)
+    ] ifFalse:[
+	self label
+    ].
+
+    "Created: / 03-10-2013 / 16:42:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 11:41:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassPO methodsFor:'accessing-private'!
+
+subject
+    "Return the real object for which the receiver
+     is a presentor.
+
+     For internal usage only."   
+
+    ^ self klass
+
+    "Created: / 01-10-2014 / 23:48:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassPO methodsFor:'converting'!
+
+asString
+    ^klass isJavaClass ifTrue:[
+	klass javaName
+    ] ifFalse:[
+	klass name
+    ].
+
+    "Created: / 04-04-2012 / 13:00:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 26-08-2013 / 10:27:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassPO methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    "/ showPrefix := nil.
+
+    super initialize.
+    showPrefix := false.
+
+    "Modified: / 20-10-2013 / 02:38:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+initializeWithClass: aClass
+
+    klass := aClass.
+    showPrefix := false.
+
+    "Created: / 20-05-2014 / 09:56:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassPO methodsFor:'testing'!
+
+isSmallSenseClassPO
+    ^ true
+! !
+
+!ClassPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ClassSearchDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,226 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSearchDialog subclass:#ClassSearchDialog
+	instanceVariableNames:'matchFullyQualifiedClassNameHolder
+		matchFullyQualifiedClassNameEnabledHolder
+		showOnlyInterfacesHolder'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!ClassSearchDialog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ClassSearchDialog class methodsFor:'interface specs-content'!
+
+optionsPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::ClassSearchDialog andSelector:#optionsPaneSpec
+     SmallSense::ClassSearchDialog new openInterface:#optionsPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: optionsPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Search Options...'
+         name: 'Search Options...'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 634 25)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (VerticalPanelViewSpec
+             name: 'Options'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             horizontalLayout: fit
+             verticalLayout: fit
+             horizontalSpace: 3
+             verticalSpace: 3
+             component: 
+            (SpecCollection
+               collection: (
+                (CheckBoxSpec
+                   label: 'Match fully qualified class names'
+                   name: 'CheckBox1'
+                   model: matchFullyQualifiedClassNameHolder
+                   extent: (Point 634 25)
+                 )
+                )
+              
+             )
+           )
+          )
+        
+       )
+     )
+! !
+
+!ClassSearchDialog methodsFor:'accessing-defaults'!
+
+defaultTitle
+    ^ (resources string: 'Search Class...')
+
+    "Created: / 05-05-2014 / 23:39:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassSearchDialog methodsFor:'aspects'!
+
+matchFullyQualifiedClassNameEnabledHolder
+    <resource: #uiAspect>
+
+    "automatically generated by UIPainter ..."
+
+    "*** the code below creates a default model when invoked."
+    "*** (which may not be the one you wanted)"
+    "*** Please change as required and accept it in the browser."
+    "*** (and replace this comment by something more useful ;-)"
+
+    matchFullyQualifiedClassNameEnabledHolder isNil ifTrue:[
+        matchFullyQualifiedClassNameEnabledHolder := true asValue.
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/       matchFullyQualifiedClassNameEnabledHolder addDependent:self.
+"/       matchFullyQualifiedClassNameEnabledHolder onChangeSend:#matchFullyQualifiedClassNameEnabledHolderChanged to:self.
+    ].
+    ^ matchFullyQualifiedClassNameEnabledHolder.
+!
+
+matchFullyQualifiedClassNameHolder
+    <resource: #uiAspect>
+
+
+    matchFullyQualifiedClassNameHolder isNil ifTrue:[
+        matchFullyQualifiedClassNameHolder := (AspectAdaptor forAspect:#matchFullyQualifiedClassName) subject: processor.   
+        matchFullyQualifiedClassNameHolder addDependent:self.
+    ].
+    ^ matchFullyQualifiedClassNameHolder.
+
+    "Modified: / 12-12-2014 / 23:15:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showOnlyInterfacesHolder
+    "return/create the 'showOnlyIntefacesHolder' value holder (automatically generated)"
+    
+    showOnlyInterfacesHolder isNil ifTrue:[
+        showOnlyInterfacesHolder := false asValue.
+        showOnlyInterfacesHolder addDependent:self.
+    ].
+    ^ showOnlyInterfacesHolder
+
+    "Modified: / 24-04-2014 / 23:42:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showOnlyInterfacesHolder:something 
+    "set the 'showOnlyIntefacesHolder' value holder (automatically generated)"
+    
+    | oldValue  newValue |
+
+    showOnlyInterfacesHolder notNil ifTrue:[
+        oldValue := showOnlyInterfacesHolder value.
+        showOnlyInterfacesHolder removeDependent:self.
+    ].
+    showOnlyInterfacesHolder := something.
+    showOnlyInterfacesHolder notNil ifTrue:[
+        showOnlyInterfacesHolder addDependent:self.
+    ].
+    newValue := showOnlyInterfacesHolder value.
+    oldValue ~~ newValue ifTrue:[
+        self 
+            update:#value
+            with:newValue
+            from:showOnlyInterfacesHolder.
+    ].
+! !
+
+!ClassSearchDialog methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+    changedObject == matchFullyQualifiedClassNameHolder ifTrue:[
+        matchingObjectsUpdateJob restart.
+        ^ self.
+    ].
+    changedObject == showOnlyInterfacesHolder ifTrue:[
+        matchingObjectsUpdateJob restart.
+        ^ self.
+    ].  
+
+    ^ super update:something with:aParameter from:changedObject
+
+    "Created: / 27-04-2014 / 23:45:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassSearchDialog methodsFor:'initialization'!
+
+initialize  
+    super initialize.
+    processor := ClassSearchProcessor new.
+
+    "Created: / 13-12-2014 / 08:46:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassSearchDialog methodsFor:'queries'!
+
+hasOptions
+    ^ true
+
+    "Created: / 09-05-2014 / 23:59:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showOnlyInterfaces
+    ^self showOnlyInterfacesHolder value
+
+    "Created: / 18-03-2013 / 10:40:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-03-2013 / 13:32:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ClassSearchProcessor.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,132 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSearchProcessor subclass:#ClassSearchProcessor
+	instanceVariableNames:'matchFullyQualifiedClassName'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!ClassSearchProcessor class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ClassSearchProcessor methodsFor:'accessing'!
+
+matchFullyQualifiedClassName
+    ^ matchFullyQualifiedClassName
+!
+
+matchFullyQualifiedClassName:something
+    matchFullyQualifiedClassName := something.
+! !
+
+!ClassSearchProcessor methodsFor:'accessing - presentation'!
+
+label
+    "Return a label for this processor. This one is used as section label
+     in Spotter"
+
+    ^ 'Classes'
+
+    "Created: / 10-01-2015 / 06:41:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassSearchProcessor methodsFor:'searching'!
+
+matchingObjectPOsFor: objects
+    | matchQualified |
+
+    matchQualified := matchFullyQualifiedClassName == true.
+    matchQualified ifTrue:[
+        objects sort:[:a :b | a displayString < b displayString ].
+    ] ifFalse:[
+        objects sort:[:a :b | a nameWithoutPrefix < b nameWithoutPrefix ].
+    ].
+
+    ^ objects collect:[:each | 
+        (ClassPO new)
+            klass:each;
+            showPrefix:matchQualified
+    ].
+
+    "Created: / 30-04-2014 / 09:50:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-12-2014 / 23:10:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsForPattern:pattern filter: filter inEnvironment:environment relax: level 
+    | matching matchQualified |
+
+    matching := OrderedCollection new.
+    matchFullyQualifiedClassName := (matchFullyQualifiedClassName == true) or:[ pattern asString includesString:'::' ].
+    matchQualified := matchFullyQualifiedClassName. 
+    pattern notNil ifTrue:[
+        matchQualified ifFalse:[
+            environment 
+                allClassesDo:[:cls | 
+                    ((filter isNil or:[filter value: cls]) and:[(pattern match:cls nameWithoutPrefix relax: level)]) ifTrue:[
+                        matching add:cls.
+                    ].
+                ].
+        ] ifTrue:[
+            environment 
+                allClassesDo:[:cls | 
+                    ((filter isNil or:[filter value: cls]) and:[(pattern match:cls displayString relax: level)]) ifTrue:[
+                        matching add:cls
+                    ]
+                ].
+        ]
+    ].
+
+    ^ matching
+
+    "Created: / 12-12-2014 / 21:24:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-01-2015 / 17:43:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassSearchProcessor class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ClassType.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,177 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Type subclass:#ClassType
+	instanceVariableNames:'trustfullness klass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types'
+!
+
+!ClassType class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ClassType methodsFor:'accessing'!
+
+klass
+    ^ klass
+!
+
+klass:aClass
+
+    self assert: aClass notNil.
+    klass := aClass.
+    (klass == True or:[klass == False]) ifTrue: [
+        klass := Boolean
+    ].
+    "Some manual trustfullness tweaks"
+    klass == Object ifTrue:[
+        self trustfullnessAdd: -10. 
+    ]
+
+    "Modified (format): / 05-10-2013 / 00:38:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullness
+    ^ trustfullness ? 20
+
+    "Modified: / 17-05-2012 / 19:35:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullness:something
+    trustfullness := something min: 100.
+
+    "Modified: / 17-05-2012 / 19:46:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassType methodsFor:'comparing'!
+
+= another
+
+    ^self class == another class 
+        and:[klass == another klass]
+
+    "Modified: / 16-12-2011 / 13:38:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hash
+
+    ^ klass hash
+
+    "Modified: / 16-12-2011 / 13:38:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassType methodsFor:'enumerating'!
+
+classesDo:aBlock
+    "Enumerate all classes that this type represents"
+
+    ^ aBlock value: klass
+
+    "Modified: / 16-12-2011 / 13:33:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassType methodsFor:'operations'!
+
+classSide
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ self class new 
+        klass: klass class;
+        trustfullness: self trustfullness - 10;
+        yourself
+
+    "Modified: / 18-09-2013 / 02:34:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+instanceSide
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ self class new 
+        klass: klass theNonMetaclass;
+        trustfullness: self trustfullness - 10;
+        yourself
+
+    "Modified: / 18-09-2013 / 02:33:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassType methodsFor:'printing & storing'!
+
+printWithoutAnglesOn:aStream
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    klass == UndefinedObject ifTrue:[
+         'nil' printOn: aStream 
+    ] ifFalse:[
+        klass printOn: aStream
+    ].
+
+    "Modified: / 24-09-2013 / 13:46:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassType methodsFor:'testing'!
+
+isClassType
+
+    ^true
+
+    "Created: / 16-12-2011 / 02:00:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isUnknownType
+
+    ^klass == UndefinedObject
+
+    "Created: / 31-01-2014 / 01:30:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ClassType class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CodeHighlightingService.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,478 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Tools::CodeHighlightingService subclass:#CodeHighlightingService
+	instanceVariableNames:'lastLineFromChanged lastLineToChanged lastContentsList'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Services'
+!
+
+!CodeHighlightingService class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CodeHighlightingService class methodsFor:'accessing'!
+
+label
+    "Answers a short label - for UI"
+
+    ^'SmallSense - Code Highlighting'
+
+    "Created: / 27-07-2013 / 22:46:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2013 / 10:27:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'accessing'!
+
+syntaxHighlighter
+    | highlighter |
+
+    highlighter := super syntaxHighlighter.
+    highlighter == SyntaxHighlighter ifTrue:[
+        ^ SmalltalkSyntaxHighlighter
+    ].
+    highlighter == SyntaxHighlighter2 ifTrue:[
+        ^ SmalltalkSyntaxHighlighter
+    ].
+    ^ highlighter
+
+    "Created: / 26-08-2013 / 09:26:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'change & update'!
+
+sourceChanged:force
+    ^self sourceChanged: force from: nil to: nil.
+
+    "Created: / 27-07-2013 / 22:52:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+sourceChanged:force from:start to:end    
+    "Called when codeview's text changes"
+
+    (force or:[codeView reallyModified]) ifTrue:[
+        (start notNil and: [end notNil and:[start > end]]) ifTrue:[
+            lastLineFromChanged  := lastLineToChanged := nil.
+        ] ifFalse:[
+            lastLineFromChanged := start.
+            lastLineToChanged := end.   
+        ].
+        self process
+    ].
+
+    "Created: / 27-07-2013 / 22:51:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-08-2013 / 13:00:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+update:aspect with:param from:sender
+    "Invoked when an object that I depend upon sends a change notification."
+
+    textView notNil ifTrue:[
+        (sender == textView and:[aspect == #sizeOfContents]) ifTrue:[
+"/            self halt.
+"/            lastContentsList ~~ textView list ifTrue:[
+"/                lastContentsList := textView list.
+"/                self sourceChanged:true.
+"/                textView instVarNamed: #suppressNotifications put: false.
+"/            ].
+            ^self.
+        ].  
+    ].
+    super update:aspect with:param from:sender
+
+    "Modified: / 03-08-2013 / 12:39:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'event handling'!
+
+linesDeletedFrom:start to:end 
+    self sourceChanged:true from:start to:end
+
+    "Created: / 27-07-2013 / 22:51:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 01:41:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+linesInsertedFrom:start to:end 
+    self sourceChanged:true from:start to:end
+
+    "Created: / 27-07-2013 / 22:51:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 01:41:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+linesModifiedFrom:start to:end 
+    self sourceChanged:true from:start to:end
+
+    "Created: / 27-07-2013 / 22:50:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'initialization'!
+
+initialize
+    job := (Smalltalk at:#BackgroundQueueProcessingJob) 
+                named:self defaultJobName
+                on:[:interval |
+                    Error handle:[:ex |
+                        (Dialog confirm:('Error while processing source:\\',ex description,'\\Debug ?') withCRs)
+                        ifTrue:[
+                            ex reject.
+                        ]
+                    ] do:[
+                        self process:true changed: interval
+                    ]
+                ].
+
+    "Created: / 03-08-2013 / 11:08:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'private'!
+
+setHighlightedLine: line at: lineNr
+    |firstShown lastShown anyChange replaceAction list|
+
+    "textView" modified ifTrue:[
+        "/ new input arrived in the meantime
+
+        ^ self
+    ].
+"/    done ifFalse:[
+"/        "/ another coloring process has already been started.
+"/        "/ ignore this (leftover) code.
+"/        ^ self
+"/    ].
+
+    firstShown := textView firstLineShown.
+    lastShown := textView lastLineShown.
+
+    replaceAction := [:lNr :line |
+            |oldLine|
+
+            oldLine :=  list at:lNr ifAbsent:nil.
+            oldLine notNil ifTrue:[
+                line notNil ifTrue:[
+                    "/ this check is needed - there is a race
+                    "/ when the text is converted. This detects the
+                    "/ resulting error.
+                    "/ Certainly a kludge.
+
+                    oldLine string = line string ifTrue:[
+                        | i |
+
+                        "JV@2012-02-01: Remove any emphasis on leading whitespace"
+                        "(presumably created by LintHighlighter)"
+                        i := line string indexOfNonSeparator.
+                        i > 1 ifTrue:[
+                            | e |
+
+                            (e := (line emphasisAt: i - 1)) notNil ifTrue:[
+                                line emphasisFrom: 1 to: i - 1 remove: e.
+                            ]
+                        ].
+
+                        oldLine emphasis ~= line emphasis ifTrue:[
+                            textView modifiedChannel removeDependent:self.
+                            list at:lNr put:line.
+                            textView modifiedChannel addDependent:self.
+                            (lNr between:firstShown and:lastShown) ifTrue:[
+                                anyChange ifFalse:[
+                                    anyChange := true.
+                                ].
+                                textView redrawLine:lNr
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ].
+    list := textView list.  
+    replaceAction value: lineNr value: line.
+    gutterView invalidate.
+
+"/    Transcript showCR:'--> rehighlighted ', self identityHash printString.
+
+    "Created: / 03-08-2013 / 23:49:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-08-2013 / 00:55:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService methodsFor:'processing'!
+
+process
+    "(Re)starts the processing job. Should be called whenever a source 
+     must be (re)processed."
+
+    | browser |
+
+    (self syntaxHighlighters isEmptyOrNil) ifTrue:[
+        "No higlighter, nothing to do"
+        ^self
+    ].   
+
+    "/ this clobbers the codeViews modified state; therefore, we have to remember
+    "/ this info somewhere ...
+    (browser := codeView browser) notNil ifTrue:[
+        textView modified ifTrue:[
+            browser navigationState realModifiedState: true
+        ].
+        textView modifiedChannel setValue:false.
+    ].
+
+    ((lastLineFromChanged isNil and:[lastLineToChanged isNil]) 
+        or:[lastLineFromChanged == 1 and:[lastLineToChanged == textView size]]) ifTrue:[
+        job stopAndRemoveAll.
+        job add: nil.
+    ] ifFalse:[
+        job add:(lastLineFromChanged to:lastLineToChanged).
+    ]
+
+    "Created: / 03-08-2013 / 11:07:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 06-08-2013 / 03:41:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+process: delayed
+
+    ^self process: delayed changed: nil.
+
+    "Created: / 27-07-2013 / 22:53:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-08-2013 / 11:11:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+process: delayed changed: interval
+
+    |oldCode oldCodeList newCode newCodeList newCodeRefetch newCodeListRefetch elements cls mthd highlighters|
+
+    done := false.
+    modified := false.
+    codeView syntaxElements: nil.
+    codeView syntaxElementSelection: nil.
+
+    highlighters := self syntaxHighlighters.
+
+    cls := codeView klass.
+    (cls notNil and:[cls isObsolete]) ifTrue:[
+        cls isMeta ifTrue:[
+            cls := (Smalltalk at:cls theNonMetaclass name) class
+        ] ifFalse:[
+            cls := Smalltalk at:cls name
+        ].
+    ].
+    mthd := codeView methodHolder value.
+
+    "textView" modified ifFalse:[
+        oldCodeList := textView list copy.
+        "/ Sometimes oldCodeList is not a string collection
+        "/ but Array (usually with one nil element). In that case
+        "/ #asStringWithoutEmphasis fails, so check & convert it here.
+        (oldCodeList notNil and:[oldCodeList isStringCollection not]) ifTrue:[
+            oldCodeList := oldCodeList asStringCollection.
+        ].
+        "textView" modified ifFalse:[
+            oldCodeList notNil ifTrue:[
+                oldCode := oldCodeList asStringWithoutEmphasis.
+                "textView" modified ifFalse:[
+                    Screen currentScreenQuerySignal answer:codeView device do:[
+                        Parser parseErrorSignal handle:[:ex |
+"/                            |errMsg|
+
+"/                            errMsg := ex description asStringCollection first asString.
+
+                            "/ Transcript topView raiseDeiconified.
+                            "/ Transcript showCR:'ParseError: ', ex description.
+"/ self halt.
+                            "/ self showInfo:(errMsg colorizeAllWith:Color red).
+                            newCode := nil.
+                        ] do:[
+                            | codeAspect |
+                            
+                            elements := ParseTreeIndex new.
+                            codeAspect := codeView codeAspect.
+
+                            "/ switch codeAspect
+                            "/ case method
+                                codeAspect == SyntaxHighlighter codeAspectMethod ifTrue:[
+                                    (interval notNil and:[interval size == 1 and:[highlighters first respondsTo:#formatMethod:source:line:number:in:using:]]) ifTrue:[
+                                        newCodeList := oldCodeList.
+                                        newCode := newCodeList asString.
+                                    ] ifFalse:[
+                                        newCodeList := oldCode asStringCollection.
+                                        newCode := oldCode asText. 
+                                    ].
+                                    newCodeListRefetch := [].
+                                    newCodeRefetch := [].
+                                    highlighters do:[:h|
+                                        (interval notNil and:[h respondsTo:#formatMethod:source:line:number:in:using:]) ifTrue:[
+                                            newCodeListRefetch value.   
+                                            interval do:[:lnr |
+                                                | ln |
+
+                                                ln := newCodeList at: lnr ifAbsent:[nil].
+                                                ln notEmptyOrNil ifTrue:[
+                                                    | nln |
+
+                                                    nln := h formatMethod:mthd source:newCode line: ln string number: lnr in:cls using:syntaxPreferences.
+                                                    nln ~~ ln ifTrue:[
+                                                        delayed ifTrue:[
+                                                            codeView sensor 
+                                                                pushUserEvent:#setHighlightedLine:at:
+                                                                for:self
+                                                                withArguments:(Array with:nln with: lnr).                                                                                                                                                                                                                     
+                                                        ] ifFalse:[
+                                                           self setHighlightedLine: nln at: lnr.
+                                                        ].
+                                                        newCodeList at: lnr put: nln.
+                                                       newCodeListRefetch := [].
+                                                       newCodeRefetch := [ newCode := newCodeList asString. newCodeListRefetch := [] ].   
+                                                    ]
+                                                ]
+                                            ].
+
+                                        ] ifFalse:[
+                                            newCodeRefetch value.
+                                            newCode := h formatMethod:mthd source:newCode in:cls using:syntaxPreferences elementsInto: elements.
+                                            newCodeListRefetch := [ newCodeList := newCode asStringCollection. newCodeRefetch := [] ].
+                                            newCodeRefetch := [  ].
+                                        ].
+                                    ].
+                                ] ifFalse:[
+                            "/ case expession
+                                codeAspect == (SyntaxHighlighter codeAspectExpression) ifTrue:[
+                                    newCodeList := oldCode asStringCollection.
+                                    newCode := oldCode asText.
+                                    highlighters do:[:h|
+                                        newCodeRefetch value.
+                                        newCode := h formatExpression:newCode in:cls elementsInto: elements.
+                                        newCodeListRefetch := [ newCodeList := newCode asStringCollection. newCodeRefetch := [] ].
+                                        newCodeRefetch := [  ].
+                                    ].
+                                ] ifFalse:[
+                            "/case class definition
+                               codeView codeAspect == #classDefinition ifTrue:[
+                                    (interval notNil and:[highlighters first respondsTo:#formatClassDefinition:line:number:in:]) ifTrue:[
+                                         newCodeList := oldCodeList.
+                                         newCode := newCodeList asString.
+                                    ] ifFalse:[
+                                         newCodeList := oldCode asStringCollection.
+                                         newCode := oldCode asText. 
+                                    ].
+                                    newCodeListRefetch := [].
+                                    newCodeRefetch := [].
+
+                                    highlighters do:[:h|
+                                       (interval notNil and:[h respondsTo:#formatClassDefinition:line:number:in:]) ifTrue:[
+                                            newCodeListRefetch value.
+                                            interval do:[:lnr |
+                                                | ln |
+
+                                                ln := oldCodeList at: lnr ifAbsent:[nil].
+                                                ln notEmptyOrNil ifTrue:[
+                                                    | nln |
+
+                                                    nln := h formatClassDefinition:newCode line: ln string number: lnr in:cls.
+                                                    nln ~~ ln ifTrue:[
+                                                        delayed ifTrue:[
+                                                            codeView sensor 
+                                                                pushUserEvent:#setHighlightedLine:at:
+                                                                for:self
+                                                                withArguments:(Array with:nln with: lnr).                                                                                                 
+                                                       ] ifFalse:[
+                                                           self setHighlightedLine: nln at: lnr.
+                                                       ].
+                                                       newCodeList at: lnr put: nln.
+                                                       newCodeListRefetch := [].
+                                                       newCodeRefetch := [ newCode := newCodeList asString. newCodeListRefetch := [] ].   
+                                                    ]
+                                                ]
+                                            ].
+                                        ] ifFalse:[
+                                            newCodeRefetch value.
+                                            newCode := h formatClassDefinition:newCode in:cls elementsInto: elements.
+                                            newCodeListRefetch := [ newCodeList := newCode asStringCollection. newCodeRefetch := [] ].
+                                            newCodeRefetch := [  ].
+                                        ]
+                                   ].
+                               ]]].
+                        ]
+                    ].
+                    newCode notNil ifTrue:[
+                        "textView" modified ifFalse:[
+                            newCode ~= oldCodeList ifTrue:[
+                                | newCodeText |
+
+                                newCodeText := newCode.
+                                newCode := newCode asStringCollection.
+                                "textView" modified ifFalse:[
+                                    done := true.
+                                    elements source: newCodeText.
+                                    textView notNil ifTrue:[
+                                        "/ must add this event - and not been interrupted
+                                        "/ by any arriving key-event.
+                                        "/ self showInfo:nil.
+                                        delayed ifTrue:[
+                                            codeView sensor
+                                                pushUserEvent:#setHighlightedCode:elements:
+                                                for:self
+                                                withArguments:(Array with:newCode with: elements).
+                                                "/self delayedUpdateBufferLabelWithCheckIfModified
+                                        ] ifFalse:[
+                                            textView contents: newCode.
+                                            codeView syntaxElements: elements.
+                                            gutterView invalidate.
+                                        ]
+                                    ]
+                                ]
+                            ].
+                        ]
+                    ]
+                ] "/ ---
+            ]
+        ]
+    ]
+
+    "Created: / 03-08-2013 / 11:11:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 01:41:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeHighlightingService class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CodeNavigationService.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,338 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Tools::CodeNavigationService subclass:#CodeNavigationService
+	instanceVariableNames:'currentNodeHolder'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Services'
+!
+
+Object subclass:#Navigator
+	instanceVariableNames:'service button'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CodeNavigationService
+!
+
+!CodeNavigationService class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CodeNavigationService class methodsFor:'accessing'!
+
+label
+    "Answers a short label - for UI"
+
+    ^'SmallSense - Code Navigation'
+
+    "Created: / 27-07-2013 / 22:46:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2013 / 10:27:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService methodsFor:'accessing'!
+
+browser
+    ^ codeView browser.
+
+    "Created: / 24-09-2013 / 23:38:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+codeView
+    ^ codeView
+
+    "Created: / 26-11-2013 / 22:58:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+environment
+    | browser |
+
+    browser := self browser.
+    ^ browser notNil ifTrue:[browser environment] ifFalse:[Smalltalk]
+
+    "Created: / 24-09-2013 / 23:38:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService methodsFor:'event handling'!
+
+button1Press
+    | node |
+
+    node := currentNodeHolder value.
+    node notNil ifTrue:[
+        | navigator |
+
+        navigator := Navigator new
+                        service: self;
+                        button: 1.
+        navigator navigateTo: node.
+
+    ].
+
+    ^self.
+
+    "Created: / 14-02-2010 / 18:43:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-11-2011 / 14:58:02 / cg"
+    "Modified: / 24-09-2013 / 10:02:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+button1PressForMessageNode: node
+
+    ^self button1PressForSelector: node parent selector.
+
+    "Created: / 21-02-2012 / 14:30:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+button1PressForVariableNode: node
+    | name value |
+
+    value := nil.
+    node isGlobalVariable ifTrue:[
+        name := node name asSymbolIfInterned.
+        name notNil ifTrue:[
+            value := Smalltalk at: node name asSymbol.
+        ].
+        value notNil ifTrue:[
+            value isBehavior ifTrue:[
+                self browseClass: value.
+            ] ifFalse:[
+                value inspect.
+            ]
+        ]
+    ]
+
+    "Created: / 21-02-2012 / 14:30:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 06-12-2013 / 15:41:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+button2Press
+
+    | sel |
+    sel := codeView syntaxElementSelection.
+    (sel notNil and:[sel node isMessage]) ifTrue:[^self button2PressForSelector: sel node selector].
+
+    "Created: / 14-02-2010 / 18:43:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-03-2012 / 16:49:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    "/ 
+
+    super initialize.
+    currentNodeHolder := ValueHolder new.
+
+    "Modified: / 23-09-2013 / 03:51:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService methodsFor:'private'!
+
+highlightElement:element
+    super highlightElement:element.
+    element notNil ifTrue:[
+        currentNodeHolder value: element node.
+    ] ifFalse:[
+        currentNodeHolder value: nil.
+    ].
+
+    "Created: / 23-09-2013 / 03:52:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showMenu: menu
+    menuShown := menu.
+    menuShown notNil ifTrue:[
+        menuShown showAtPointer
+    ].
+
+    "Created: / 24-09-2013 / 23:43:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService::Navigator methodsFor:'accessing'!
+
+browser
+    ^ service browser
+
+    "Created: / 24-09-2013 / 23:37:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+button
+    ^ button
+!
+
+button:something
+    button := something.
+!
+
+environment
+    ^ service environment
+
+    "Created: / 24-09-2013 / 23:37:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+service
+    ^ service
+!
+
+service:something
+    service := something.
+! !
+
+!CodeNavigationService::Navigator methodsFor:'navigation'!
+
+navigateTo: node
+    node navigateToUsing: self
+
+    "Created: / 24-09-2013 / 10:03:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService::Navigator methodsFor:'navigation - Java'!
+
+navigateToMessageSend: node
+    | binding className selector toolbox |
+
+    binding := node binding .
+    binding isNil ifTrue:[ ^ nil ].
+    className := binding declaringClass compoundName asStringWith: $/.
+    selector := binding selector , binding signature.
+
+    toolbox := JavaToolbox new
+                browser: self browser;
+                environment: self environment;
+                yourself.
+    button == 1 ifTrue:[
+         service showMenu: (toolbox implementorMenuFor: selector inClassNamed: className).
+         ^ self.
+    ].
+    button == 1 ifTrue:[
+         service showMenu: (toolbox sendersMenuFor: selector inClassNamed: className).
+         ^ self.
+    ].
+
+    "Created: / 24-09-2013 / 23:10:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-09-2013 / 10:01:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+navigateToTypeReference: node
+    | classType className classes |
+
+    classType := node resolvedType.
+    classType notNil ifTrue:[
+        className := node resolvedType leafComponentType compoundName asStringWith: $/.
+    ] ifFalse:[ 
+        | unit typeName |
+
+        unit := service codeView syntaxElements tree.
+        typeName := node getTypeName. "/ returns char[][]
+        typeName size == 1 ifTrue:[
+            "/ Search imports...
+            unit imports do:[:import | 
+                | importedName typeName |
+
+                importedName := import getImportName. "/ returns char[][].                                
+                importedName last = typeName last ifTrue:[ 
+                    className := import tokens asStringWith:$/.
+                ].
+            ].
+        ] ifFalse:[ 
+            className := typeName asStringWith: $/.
+        ].
+        "/ If not imported, Try compilation unit's package...
+        className isNil ifTrue:[ 
+            className := (unit currentPackage tokens asStringWith: $/) , '/' , node token.
+        ].
+    ].
+    "/ Kludge - support both old and new Java class naming scheme
+    classes := (JavaClass canUnderstand: #binaryName) 
+                    ifTrue:[self environment allClasses select:[:cls | cls isJavaClass and:[cls binaryName = className]]]
+                    ifFalse:[self environment allClasses select:[:cls | cls isJavaClass and:[cls name = className]]].
+
+    classes isEmpty ifTrue:[
+        service codeView textView flash.
+        ^ self.
+    ].
+    classes size == 1 ifTrue:[
+        service browseClass: classes anElement.    
+        ^ self.
+    ].
+    self halt: 'Not yet supported'.
+
+    "Created: / 24-09-2013 / 10:16:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 06-08-2014 / 15:17:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService::Navigator methodsFor:'navigation - Smalltalk'!
+
+navigateToMessageNode: node
+    "/ Implementors
+    button == 1 ifTrue:[
+        "/ Use legacy code...
+        service button1PressForSelector: node selector.         
+        ^ self
+    ].
+    button == 2 ifTrue:[
+        "/ Use legacy code...
+        service button2PressForSelector: node selector.         
+        ^ self                                                  
+    ].
+
+    "Created: / 24-09-2013 / 10:06:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+navigateToVariableNode: node
+    "/ Use legacy code for now...
+    button == 1 ifTrue:[
+        service button1PressForVariableNode: node .         
+    ]
+
+    "Created: / 24-09-2013 / 10:06:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CodeNavigationService class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompletionContext.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,180 @@
+"{ Encoding: utf8 }"
+
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CompletionContext
+	instanceVariableNames:'environment node position support'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core'
+!
+
+!CompletionContext class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CompletionContext class methodsFor:'instance creation'!
+
+node: node position: position
+
+    ^self new node: node position: position
+
+    "Created: / 26-11-2011 / 16:22:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionContext methodsFor:'accessing'!
+
+environment
+    "Return an system environment for completion."
+
+    ^ environment
+
+    "Modified (comment): / 13-05-2014 / 11:54:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+environment:aSystemEnvironment
+    "Sets an envirronment for completion. Only classes and/or methods in
+     the environment are offered for completion"
+    environment := aSystemEnvironment.
+
+    "Modified (comment): / 13-05-2014 / 11:55:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+language
+    "Return a programming language in which to complete. i.e., the language of edited source code"
+
+    | lang |
+
+    lang := self textView editedLanguage.
+    lang isNil ifTrue:[ 
+        lang := support language.
+    ].
+    ^ lang
+
+    "Modified: / 10-03-2015 / 10:04:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+node
+    ^ node
+!
+
+position
+    ^ position
+!
+
+support
+    ^ support
+!
+
+textView
+    ^ support textView
+
+    "Created: / 11-02-2015 / 23:50:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionContext methodsFor:'initialization'!
+
+node:nd position: pos
+
+    node := nd.
+    position := pos.
+
+    "Created: / 26-11-2011 / 16:22:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-10-2013 / 23:31:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+support: anEditSupport
+    support := anEditSupport.
+
+    "Modified: / 21-01-2014 / 23:31:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionContext methodsFor:'private'!
+
+wordBeforeCursor
+    ^ support wordBeforeCursor.
+
+    "Created: / 27-09-2013 / 15:53:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-03-2014 / 23:03:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+wordBeforeCursorConsisitingOfCharactersMatching: characterMatchBlock
+    ^ support wordBeforeCursorConsisitingOfCharactersMatching: characterMatchBlock
+
+    "Created: / 20-10-2013 / 00:17:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-03-2014 / 23:03:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionContext methodsFor:'queries'!
+
+isAfterNode
+    ^ node notNil and:[node endPosition < (position - 1)]
+
+    "Created: / 26-11-2011 / 16:24:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-10-2013 / 23:31:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isBeforeNode
+    ^node notNil and:[position < node startPosition]
+
+    "Created: / 26-11-2011 / 16:24:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-09-2013 / 13:11:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isInNode
+    ^ node notNil and:[(position - 1) between:node startPosition and:node endPosition]
+
+    "Created: / 26-11-2011 / 16:24:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-10-2013 / 23:31:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionContext class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompletionController.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,530 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+EditTextViewCompletionSupport subclass:#CompletionController
+	instanceVariableNames:'support seqno'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core'
+!
+
+!CompletionController class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CompletionController class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!CompletionController methodsFor:'accessing'!
+
+completionEngine
+    | engineClass |
+
+    engineClass := self completionEngineClass.
+    ^ engineClass notNil 
+        ifTrue:[ engineClass new ]
+        ifFalse:[ nil ].
+
+    "Created: / 18-05-2014 / 11:58:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+environment
+    ^ support notNil 
+        ifTrue:[support environment]
+        ifFalse:[Smalltalk].
+
+    "Created: / 18-05-2014 / 11:53:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+support
+    ^ support
+!
+
+support:anEditSupport
+    support := anEditSupport.
+! !
+
+!CompletionController methodsFor:'accessing-classes'!
+
+completionEngineClass
+    ^ support notNil 
+        ifTrue:[ support completionEngineClass ]
+        ifFalse:[ nil ].
+
+    "Created: / 18-05-2014 / 11:55:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionController methodsFor:'events'!
+
+handleKeyPress:key x:x y:y
+
+    key == #Control_L ifTrue:[
+        completionView notNil ifTrue:[
+            ^ false.
+        ].
+    ].
+
+    key == #CodeCompletion  ifTrue: [
+        autoSelect := true.    
+        self startCompletionProcess.
+        ^ true
+    ].
+
+    (key == #BackSpace or:[key == #BasicBackspace]) ifTrue:[
+        | c |
+
+        c := editView characterBeforeCursor.
+        (c notNil and:[c isAlphaNumeric]) ifTrue:[
+             ^ false
+        ].
+    ].     
+
+
+    completionView notNil ifTrue:[
+        (key == #Return and:[completionView hasSelection]) ifTrue:[
+            self complete.
+            ^ true.
+        ].
+        key == #Tab ifTrue:[ 
+            self handleKeyPressTab.  
+            ^ true
+        ].
+        key isCharacter ifTrue:[
+            (self updateSelectionAfterKeyPress: key) ifTrue:[ 
+                ^ true
+            ].
+        ].
+    ].
+    ^ super handleKeyPress:key x:x y:y
+
+    "Created: / 27-09-2013 / 15:38:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-06-2014 / 10:17:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+handleKeyPressTab
+    "Tab has been pressed, try to complete longest common prefix"
+
+    | first prefix matching longest minlen |
+
+    first := completionView list first.
+    prefix := self prefixAlreadyWritten.
+    matching := OrderedCollection new.
+    minlen := SmallInteger maxVal.
+    completionView list do:[:po |
+        | s |
+
+        s := po stringToComplete.
+        (s startsWith: prefix) ifTrue:[
+            matching add: po -> s.
+            minlen := minlen min: s size.
+        ].
+    ].
+    matching isEmpty ifTrue:[
+        completionView flash.
+        ^self.
+    ].
+    matching size == 1 ifTrue:[
+        self complete: matching first key.
+    ].
+
+    longest := String streamContents:[:s |
+        | i |
+
+        s nextPutAll: prefix.
+        i := prefix size + 1.
+        [ i <= minlen ] whileTrue:[
+            | c |
+
+            c := matching first value at: i.
+            (matching allSatisfy:[:e|(e value at: i) == c]) ifTrue:[
+                s nextPut:c.
+                i := i + 1.
+            ] ifFalse:[
+                "/ terminate the loop    
+                i := minlen + 2.
+            ]
+        ]
+    ].
+    longest size = prefix size ifTrue:[
+        completionView flash.
+        ^self.
+    ].
+    editView insertStringAtCursor:(longest copyFrom: prefix size + 1).
+
+    "Created: / 31-03-2014 / 22:55:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-05-2014 / 13:55:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+postKeyPress:key
+    seqno := seqno + 1.
+    seqno == SmallInteger maxVal ifTrue:[
+        seqno := 0.
+    ].
+
+    UserPreferences current immediateCodeCompletion ifFalse:[
+        "/ only update, if already open
+        completionView isNil ifTrue:[^ self].
+    ].
+
+"/    (key == #BackSpace or:[key == #BasicBackspace]) ifTrue:[
+"/        self closeCompletionView.
+"/        ^ self
+"/    ].
+
+    key isCharacter ifTrue:[
+        key isLetterOrDigit not ifTrue:[
+            "/ Hack for Java - should be delegated to completion engine    
+            (key == $. and:[support notNil and:[ support language isJavaLike ]]) ifTrue:[ 
+                ^ self
+            ].
+            self closeCompletionView
+        ] ifFalse:[
+            | c |
+
+            c := editView characterBeforeCursor.
+            (c notNil and:[c isLetterOrDigit]) ifTrue:[
+                c := editView characterUnderCursor.
+                c isSeparator ifTrue:[
+                    autoSelect := false.
+                    self updateCompletionList.
+                ].
+            ]
+        ].
+        ^ self
+    ].
+
+    "Created: / 28-09-2013 / 00:21:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-05-2014 / 13:53:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionController methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    "/ support := nil.
+    seqno := 0.
+
+    "/ super initialize.   -- commented since inherited method does nothing
+
+    "Modified: / 02-05-2015 / 22:07:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionController methodsFor:'private'!
+
+complete
+    self complete: completionView selection.
+
+    "Created: / 27-09-2013 / 15:38:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-03-2014 / 23:22:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+complete: item
+    ^ self complete: item afterKeyPress: nil
+
+    "Created: / 31-03-2014 / 23:21:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:53:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+complete: item afterKeyPress: keyOrNil
+     self closeCompletionView.
+     item insert.
+     keyOrNil notNil ifTrue:[  
+         support keyPressIgnored.
+     ].
+
+    "Created: / 11-08-2014 / 14:53:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+prefixAlreadyWritten
+    | list first |
+
+    completionView notNil ifTrue:[ 
+        list := completionView list.
+        list notEmptyOrNil ifTrue:[ 
+            first := list first.
+            (completionView list allSatisfy:[:e | e class == first class ]) ifTrue:[ 
+                ^ first stringAlreadyWritten 
+            ]
+        ]
+    ].
+    ^ support wordBeforeCursor string .
+
+    "Created: / 18-05-2014 / 13:55:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-06-2014 / 11:40:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stopCompletionProcess
+    "kill any background completion process"
+
+    editView sensor flushUserEventsFor: self.     
+    super stopCompletionProcess
+
+    "Created: / 02-10-2013 / 15:09:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-10-2013 / 11:03:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateCompletionList
+    "called for keypress events"
+
+    completionView isNil ifTrue:[
+        super updateCompletionList
+    ] ifFalse:[
+         self updateSelection.
+    ].
+
+    "Created: / 27-09-2013 / 15:58:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-09-2013 / 00:15:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSelection
+    "Updates selection in completion view based on currently typed partial 
+     text. Return true if the complection window should be closed or false
+     if it shall be kept open. "
+
+    ^ self updateSelectionAfterKeyPress: nil
+
+    "Created: / 27-09-2013 / 16:16:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 17-06-2014 / 07:24:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSelectionAfterKeyPress: keyOrNil
+    "Updates selection in completion view based on currently typed partial 
+     text. Return true if the complection window should be closed or false
+     if it shall be kept open.
+
+     If `keyOrNil` is not nil, then it's a key press that triggered the update
+     which HAS NOT YET been processed by a `editView`.
+     "
+
+    | list prefix matcher1 matches1 matcher2 matches2 |
+
+    list := completionView list.
+    matcher1 := CompletionEngine exactMatcher.
+    matcher2 := CompletionEngine inexactMatcher.
+    prefix := self prefixAlreadyWritten.
+    keyOrNil isCharacter ifTrue:[ 
+        prefix := prefix , keyOrNil
+    ].
+    matches1 := list select:[:po | matcher1 value: prefix value: po stringToComplete ].
+    matches1 notEmptyOrNil ifTrue:[
+        matches1 size == 1 ifTrue:[
+            | selection completeElectric |
+
+            selection := matches1 anElement.
+            completeElectric := (UserPreferences current smallSenseCompleteIfUnambiguous) and:[ support electricInsertSuppressed not ].
+            (completeElectric and: [(editView sensor hasKeyEventFor:editView) not]) ifTrue:[
+                self complete: selection afterKeyPress: keyOrNil.
+                ^ true
+            ] ifFalse:[ 
+                completionView selection: selection
+            ].
+        ] ifFalse:[
+            | selection |
+
+            selection := matches1 inject: matches1 anElement into:[:mostrelevant :each |
+                each relevance > mostrelevant relevance 
+                    ifTrue:[each]
+                    ifFalse:[mostrelevant]
+            ].
+            completionView selection: selection.
+        ].
+        ^ false
+    ].
+
+    matches2 := completionView list select:[:po | matcher2 value: prefix value: po stringToComplete ].
+    matches2 notEmptyOrNil ifTrue:[
+        matches2 size == 1 ifTrue:[
+            completionView selection:  matches2 anElement.
+        ] ifFalse:[
+            | selection |
+
+            selection := matches2 inject: matches2 anElement into:[:mostrelevant :each |
+                each relevance > mostrelevant relevance 
+                    ifTrue:[each]
+                    ifFalse:[mostrelevant]
+            ].
+            completionView selection: selection.
+        ]
+    ] ifFalse:[
+        completionView selection: nil.
+    ].
+    ^ false.
+
+    "Created: / 17-06-2014 / 07:19:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-05-2015 / 22:07:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionController methodsFor:'private-API'!
+
+closeCompletionView
+    |v|
+
+    self stopCompletionProcess.
+    (v := completionView) notNil ifTrue:[
+        completionView := nil.
+        "/ let it close itself - avoids synchronization problems
+        v sensor
+            pushUserEvent:#value
+            for:[ v topView destroy ].
+    ].
+
+    "Created: / 02-10-2013 / 13:57:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 21:14:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+computeCompletions
+    "Actually compute the completions and update the completion view."  
+
+    | completions |
+
+    editView sensor flushUserEventsFor: self.
+
+    "/ Wait a while to give user chance finish typing.
+    "/ This also reduces CPU consumption by avoiding
+    "/ useless computation
+    Delay waitForMilliseconds: 200. 
+
+    completions := self computeCompletionsInContext.
+    completions notEmptyOrNil ifTrue:[
+        editView sensor pushUserEvent: #updateCompletions:sequence: for: self withArguments: (Array with: completions with: seqno)
+    ].
+
+    "Created: / 27-09-2013 / 13:12:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-05-2014 / 11:50:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+computeCompletionsInContext
+    | context |
+
+    context := CompletionContext new.
+    context environment: self environment.
+    context support: support.
+    ^self computeCompletionsInContext: context.
+
+    "Created: / 18-05-2014 / 11:50:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+computeCompletionsInContext: aCompletionContext
+    | engine |
+
+    engine := self completionEngine.
+    ^engine notNil 
+        ifTrue:[ engine complete: aCompletionContext ]
+        ifFalse:[ nil ]
+
+    "Created: / 18-05-2014 / 11:53:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+openCompletionView
+    self openCompletionView: #()
+
+    "Created: / 27-09-2013 / 16:17:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+openCompletionView: list
+    "Makes sure the completion view is opened and with given `list`."
+    
+    | movePos topView x y  windowExtent screenExtent |
+    "/ move the window
+
+    list isEmpty ifTrue:[ ^ self ].
+    list = #( 'Busy...' ) ifTrue:[ ^ self ].  
+
+    x := (editView xOfCol:editView cursorCol  inVisibleLine:editView cursorLine)
+            - 16"icon" - (editView widthOfString:  "support wordBeforeCursor"list first stringAlreadyWritten) - 5"magic constant".
+    y := editView yOfCursor + editView font maxHeight + 3.
+    movePos := (editView originRelativeTo: nil) + (x @ y).
+
+    completionView isNil ifTrue:[
+
+        completionView := CompletionView new.
+        completionView completionController: self.  
+        completionView list:list.
+        completionView font: editView font.
+        topView := completionView.
+
+        windowExtent := completionView extent copy.
+        screenExtent := Screen current monitorBoundsAt: movePos.
+        (screenExtent height) < (movePos y + windowExtent y) ifTrue:[
+            movePos y: (movePos y - windowExtent y - editView font maxHeight - 5).
+        ].
+        topView origin:movePos.
+"/        topView resizeToFit.
+        self updateSelection ifFalse:[
+            topView open.
+        ].
+    ] ifFalse:[
+        completionView list:list.
+        self updateSelection.
+"/        topView := completionView topView.
+"/        topView ~~ completionView ifTrue:[
+"/            topView origin:movePos.
+"/            topView resizeToFit.
+"/        ]
+    ].
+
+    "Created: / 27-09-2013 / 14:01:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-05-2014 / 11:30:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateCompletions: completionResult sequence: sequence
+    seqno == sequence ifTrue:[
+        self openCompletionView: completionResult 
+    ].
+
+    "Created: / 03-10-2013 / 07:14:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-10-2013 / 11:02:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionController class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompletionEngine.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,202 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CompletionEngine
+	instanceVariableNames:'textView result context'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core'
+!
+
+!CompletionEngine class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CompletionEngine class methodsFor:'accessing'!
+
+exactMatcher
+    "Return a match block returning true, if given selector start with given prefix"
+
+    ^ [ :prefix :selector | selector startsWith: prefix ]
+
+    "Created: / 08-04-2014 / 21:31:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+inexactMatcher
+    "Return a match block returning true, if given prefix matches given selector"
+
+    ^ [ :prefix :selector |
+        prefix size < 5 ifTrue:[
+            selector startsWith: prefix.
+        ] ifFalse:[
+            | part |
+
+            part := selector copyTo: (prefix size min: selector size).
+            (prefix levenshteinTo: part) < 15
+        ].
+    ].
+
+    "Created: / 08-04-2014 / 21:30:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matcher
+    "Return a match block returning true, if given prefix matches given selector"
+
+    ^ [ :prefix :selector |
+        prefix size < 5 ifTrue:[
+            selector startsWith: prefix.
+        ] ifFalse:[
+            | part |
+
+            part := selector copyTo: (prefix size min: selector size).
+            (prefix levenshteinTo: part) < 15
+        ].
+    ].
+
+    "Created: / 02-04-2014 / 23:30:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngine class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CompletionEngine
+
+    "Created: / 02-10-2013 / 13:11:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngine methodsFor:'completion'!
+
+complete: aCompletionContext
+    "Compute completion for given completion context, taking all the information
+     from it. Returns a CompletionResult with computed completions"
+
+    context := aCompletionContext.
+    result := CompletionResult new.
+    textView := context textView.
+    result context: context.
+    ^ self complete.
+
+    "Created: / 21-01-2014 / 23:07:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:52:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngine methodsFor:'completion-individual'!
+
+addMethodsStartingWith: prefix
+    ^ self addMethodsStartingWith: prefix stripOff: nil filter: nil
+
+    "Created: / 24-07-2013 / 13:10:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-04-2014 / 21:36:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsStartingWith: prefix stripOff: stripoffPrefix
+    ^ self addMethodsStartingWith: prefix stripOff: stripoffPrefix filter: nil
+
+    "Created: / 08-04-2014 / 21:36:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsStartingWith: prefix stripOff: stripoffPrefix filter: filterOrNil
+    | matcher |
+
+    matcher := stripoffPrefix isEmptyOrNil ifTrue:[ CompletionEngine inexactMatcher ] ifFalse:[ CompletionEngine exactMatcher ].
+    ^ self addMethodsStartingWith: prefix stripOff: stripoffPrefix filter: filterOrNil matcher: matcher.
+
+    "Created: / 08-04-2014 / 21:35:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsStartingWith: prefix stripOff: stripoffPrefix filter: filterOrNil matcher: matcher
+    | matchPrefix selectors filter |
+
+    selectors := Dictionary new.
+    matchPrefix := stripoffPrefix isNil ifTrue:[ prefix ] ifFalse:[ stripoffPrefix , prefix ].
+    filter := filterOrNil  isNil ifTrue:[ [:method | true ] ] ifFalse:[ filterOrNil  ].
+
+    context environment allMethodsWithSelectorDo:[:mthd :selector|
+        (mthd isSynthetic not and:[(filter value: mthd) and:[ matcher value: matchPrefix value: selector]]) ifTrue:[
+                | class overridden |
+
+                class := mthd mclass superclass.
+                overridden := false.
+                [ overridden not and:[class notNil] ] whileTrue:[
+                    (class methodDictionary includesKey: selector) ifTrue:[
+                        overridden := true.
+                    ].
+                    class := class superclass.
+                ].
+                overridden ifFalse:[
+                    | classes |
+
+                    classes := selectors at: selector ifAbsentPut:[ Set new ].
+                    (classes includes: mthd mclass) ifFalse:[
+                        classes add: mthd mclass.
+                    ].
+                ].
+            ]
+    ].
+
+
+    selectors keysAndValuesDo: [:selector :classes |
+        result add:(PO forClasses: classes selector: selector prefix: stripoffPrefix)
+    ].
+    ^ self
+
+    "Created: / 08-04-2014 / 21:34:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-05-2014 / 11:54:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngine methodsFor:'completion-private'!
+
+complete
+    "Compute completion for `codeView`, taking all the information
+     from it. Returns a CompletionResult with computed completions"
+
+    ^ self subclassResponsibility
+
+    "Modified (comment): / 02-10-2013 / 13:33:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngine class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompletionEngineTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,144 @@
+"{ Encoding: utf8 }"
+
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractTestCase subclass:#CompletionEngineTests
+	instanceVariableNames:'engine context result codeView'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!CompletionEngineTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CompletionEngineTests class methodsFor:'queries'!
+
+isAbstract
+    "Return if this class is an abstract class.
+     True is returned here for myself only; false for subclasses.
+     Abstract subclasses must redefine again."
+
+    ^ self == SmallSense::CompletionEngineTests.
+! !
+
+!CompletionEngineTests methodsFor:'accessing'!
+
+environment
+   ^ Smalltalk
+
+    "Created: / 22-05-2014 / 16:50:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngineTests methodsFor:'accessing-classes'!
+
+completionEngineClass
+    ^ self subclassResponsibility
+
+    "Created: / 22-05-2014 / 16:38:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completionLanguage
+    ^ self subclassResponsibility
+
+    "Created: / 07-03-2015 / 10:35:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngineTests methodsFor:'running'!
+
+setUp
+    | service support  |
+
+    engine := self completionEngineClass new.
+    codeView := Tools::CodeView2 new.
+    codeView languageHolder value: self completionLanguage.
+    service := EditService new.
+    service registerIn: codeView.  
+    support := GenericEditSupport new.
+    service updateSupport: support.  
+    context := CompletionContext new.
+    context support: support.
+    context environment: self environment.
+
+    "Created: / 22-05-2014 / 16:50:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-03-2015 / 10:36:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+tearDown
+    engine := context := nil
+
+    "Created: / 22-05-2014 / 16:51:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngineTests methodsFor:'utilities'!
+
+complete: aString
+     | list textView |
+
+    list := aString asStringCollection.
+    textView := codeView textView.
+    textView list: list.
+    1 to: list size do:[:i |  
+        | line cursorCol |
+
+        line := list at: i.
+        cursorCol := line indexOf: '┃' first.
+        cursorCol ~~ 0 ifTrue:[ 
+            line := (line copyTo: cursorCol - 1) , (line copyFrom: cursorCol + 1).
+            list at: i put: line.
+            textView setCursorLine: i; setCursorCol: cursorCol.
+        ].
+    ].
+    ^ result := engine complete: context
+
+    "Created: / 22-05-2014 / 16:56:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:10:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionEngineTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompletionResult.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,92 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SortedCollection subclass:#CompletionResult
+	instanceVariableNames:'context'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core'
+!
+
+!CompletionResult class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CompletionResult class methodsFor:'instance creation'!
+
+new
+    ^ self sortBlock:[:a :b | a label < b label ].
+
+    "Created: / 26-09-2013 / 11:01:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionResult methodsFor:'accessing'!
+
+context
+    ^ context
+!
+
+context:aCompletionContext
+    context := aCompletionContext.
+    self do:[:each | each context: context ].
+
+    "Modified: / 17-10-2013 / 01:13:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionResult methodsFor:'adding & removing'!
+
+add:anObject
+    anObject context: context.
+    ^ super add: anObject
+
+    "Created: / 17-10-2013 / 01:02:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addAll:aCollection
+    "add all elements of the argument, aCollection to the receiver.
+     Returns the argument, aCollection (sigh)."
+
+    aCollection do:[:each | each context: context ].
+    ^ super addAll: aCollection
+
+    "Created: / 17-10-2013 / 01:06:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompletionView.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,198 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SimpleView subclass:#CompletionView
+	instanceVariableNames:'completionController completionContext list listHolder listView
+		selectionHolder helpHolder helpView'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface'
+!
+
+!CompletionView class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CompletionView methodsFor:'accessing'!
+
+completionContext
+    ^ completionContext
+!
+
+completionContext:aCompletionContext
+    | node |
+
+    completionContext := aCompletionContext.
+    node := completionContext node.
+    (node notNil and:[node askFor:#isMessage]) ifTrue:[ 
+        helpHolder value: 'Receiver type: ', node receiver inferedType displayString
+    ] ifFalse:[ 
+        helpHolder value: 'Up/Down to select, Enter to paste' asText.
+    ].
+
+    "Modified: / 12-08-2014 / 10:54:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completionController
+    ^ completionController
+!
+
+completionController:aCompletionController
+    completionController := aCompletionController.
+
+    "Modified: / 04-04-2014 / 14:53:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+font: aFont
+    super font: aFont.
+    listView font: aFont.
+
+    "Created: / 27-09-2013 / 14:03:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+list
+    ^ list
+!
+
+list: aCollection
+    list :=  aCollection.
+    listHolder value: aCollection.
+    self completionContext: (aCollection notEmptyOrNil ifTrue:[aCollection anElement context] ifFalse:[ nil ]).
+
+    "Created: / 27-09-2013 / 14:02:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-04-2014 / 14:56:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selection
+    ^ (listView value at: selectionHolder value).
+
+    "Created: / 27-09-2013 / 15:41:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selection: po
+    selectionHolder value: (listHolder value identityIndexOf: po)
+
+    "Created: / 27-09-2013 / 16:09:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionView methodsFor:'actions'!
+
+complete: index
+    self assert: selectionHolder value == index.
+    completionController complete.
+
+    "Created: / 27-02-2014 / 10:09:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionView methodsFor:'event handling'!
+
+keyPress:key x:x y:y
+    ^ listView keyPress:key x:x y:y
+
+    "Created: / 27-09-2013 / 14:05:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-03-2014 / 22:53:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionView methodsFor:'initialization & release'!
+
+initialize
+    | listViewScroller listViewScrollerLayout helpViewLayout |
+
+    super initialize.
+    listHolder := ValueHolder new.
+    selectionHolder := ValueHolder new.
+    helpHolder := ValueHolder new.
+
+    listViewScrollerLayout := LayoutFrame origin: 0.0 @ 0.0  corner: 1.0 @ 1.0.
+    listViewScrollerLayout bottomOffset: -20.
+    listViewScroller := ScrollableView for: SelectionInListModelView.
+    listViewScroller layout: listViewScrollerLayout.
+    self addSubView: listViewScroller.
+
+    listView := listViewScroller scrolledView.
+    listView listHolder: listHolder.
+    listView model: selectionHolder.
+    listView highlightMode: #line.
+    listView doubleClickAction:[:index | self complete: index ].
+
+    helpViewLayout := LayoutFrame origin: 0.0 @ 1.0  corner: 1.0 @ 1.0.
+    helpViewLayout topOffset: -20.
+    helpView := Label new.
+    helpView adjust: #left.
+    helpView labelChannel: helpHolder.  
+    helpView layout: helpViewLayout.
+    self addSubView: helpView.  
+
+    self extent: 400 @ 250
+
+    "Created: / 27-09-2013 / 13:56:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-04-2014 / 15:03:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionView methodsFor:'queries'!
+
+hasSelection
+    ^listView hasSelection
+
+    "Created: / 27-09-2013 / 14:10:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isPopUpView
+    ^ true
+
+    "Created: / 27-09-2013 / 13:56:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionView methodsFor:'redrawing'!
+
+flash
+    listView flash.
+
+    "Created: / 31-03-2014 / 22:56:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompletionView class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CompositeProcessor.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,224 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSearchProcessor subclass:#CompositeProcessor
+	instanceVariableNames:'processors'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!CompositeProcessor class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CompositeProcessor class methodsFor:'instance creation'!
+
+with: processor1
+    ^ self withAll: (Array with: processor1)
+
+    "Created: / 10-01-2015 / 07:00:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+with: processor1 with: processor2
+    ^ self withAll: (Array with: processor1 with: processor2)
+
+    "Created: / 10-01-2015 / 07:00:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+with: processor1 with: processor2 with: processor3
+    ^ self withAll: (Array with: processor1 with: processor2 with: processor3)
+
+    "Created: / 10-01-2015 / 07:00:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+withAll: processors
+    ^ self new processors: processors
+
+    "Created: / 10-01-2015 / 07:00:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompositeProcessor methodsFor:'accessing'!
+
+canDoNextStepFor: aPO
+    "Return true if navigation can take a next step for given PO
+     (i.e., if user can 'dive in'), false otherwise.
+     To be overriden by subclasses to avoid excessive processor creation."
+
+    ^ aPO context canDoNextStepFor: aPO
+
+    "Created: / 23-01-2015 / 22:26:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+processorForNextStepFor: aPO
+    "Return a processor for next navigation step for given PO.
+     If nil is returned, then there's no next step (i.e.,
+     a user connot 'dive in')"
+
+    ^ aPO context processorForNextStepFor: aPO
+
+    "Created: / 23-01-2015 / 22:26:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+processors
+    ^ processors
+!
+
+processors:aCollection
+    processors := aCollection asArray
+
+    "Modified: / 10-01-2015 / 06:59:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+recentlySearchedObjectPOs
+    | pos |
+
+    pos := OrderedCollection new: processors size.
+    processors do:[:processor  |
+        | bucket |
+
+        bucket := processor recentlySearchedObjectPOs.
+        bucket notEmptyOrNil ifTrue:[ 
+            | sectionPO bucketPOs|
+
+            sectionPO := PluggablePO new.
+            pos add: sectionPO.
+            sectionPO label: ((processor label bindWith: processor label with: bucket size) asText colorizeAllWith: Color gray).
+            sectionPO subject: self. "/ used as a marker that this is a group PO
+            bucketPOs := bucket.
+            bucketPOs do:[:e | e context: processor ].
+            false ifTrue:[ 
+                sectionPO children: bucketPOs.
+                sectionPO expand
+            ] ifFalse:[ 
+                pos addAll: bucketPOs.
+            ].
+
+
+
+        ].
+    ].
+    ^ pos
+
+    "Created: / 11-01-2015 / 06:25:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompositeProcessor methodsFor:'accessing - presentation'!
+
+label
+    "Return a label for this processor. This one is used as section label
+     in Spotter"
+
+    processors notEmptyOrNil ifTrue:[ 
+        processors size == 1 ifTrue:[ ^ processors anElement label ].
+        processors size == 2 ifTrue:[ ^ processors first label , ' & ' , processors second label ].
+        processors size == 2 ifTrue:[ ^ processors first label , ', ', processors second label, ' & ' , processors third label ].
+        ^ processors size , ' search processors'
+    ] ifFalse:[ 
+        ^ 'Empty'
+    ].
+
+    "Created: / 10-01-2015 / 06:44:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompositeProcessor methodsFor:'remembering'!
+
+rememberSearchObjectPO: po
+    po context rememberSearchObjectPO: po
+
+    "Created: / 11-01-2015 / 06:22:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CompositeProcessor methodsFor:'searching'!
+
+matchingObjectPOsFor: objects
+    ^ self matchingObjectPOsFor: objects label: '%1 (%2 matches)'
+
+    "Created: / 10-01-2015 / 06:54:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-01-2015 / 06:24:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectPOsFor: objects label: label
+
+    | pos |
+
+    objects isEmptyOrNil ifTrue:[ ^ #() ].
+    pos := OrderedCollection new: processors size.
+    processors with: objects do:[:processor :bucket |
+        bucket notEmptyOrNil ifTrue:[ 
+            | sectionPO bucketPOs|
+
+            sectionPO := PluggablePO new.
+            pos add: sectionPO.
+            sectionPO label: ((label bindWith: processor label with: bucket size) asText colorizeAllWith: Color gray).
+            sectionPO subject: self. "/ used as a marker that this is a group PO
+            bucketPOs := processor matchingObjectPOsFor: bucket.
+            bucketPOs do:[:e | e context: processor ].
+            false ifTrue:[ 
+                sectionPO children: bucketPOs.
+                sectionPO expand
+            ] ifFalse:[ 
+                pos addAll: bucketPOs.
+            ].
+
+
+
+        ].
+    ].
+    ^ pos
+
+    "Created: / 11-01-2015 / 06:24:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsForPattern:pattern filter: filter inEnvironment:environment
+    ^ (processors ? #()) collect: [ :processor | processor matchingObjectsForPattern:pattern filter: filter inEnvironment:environment ]
+
+    "Created: / 10-01-2015 / 06:47:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsForPattern:pattern filter:filter inEnvironment:environment relax:level
+    "superclass SmallSense::AbstractSearchProcessor says that I am responsible to implement this method"
+
+    ^ self shouldNotImplement
+
+    "Created: / 10-01-2015 / 06:45:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ConstantPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,101 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#ConstantPO
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!ConstantPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ConstantPO methodsFor:'accessing'!
+
+label
+    "Return a text to be displayed. The label may be cached
+     `label` instvar."
+
+    ^ '???'
+
+    "Created: / 20-05-2014 / 11:31:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage:aProgrammingLanguage
+    "Answers a string to complete"
+
+    ^ '???'
+
+    "Created: / 20-05-2014 / 11:32:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ConstantPO methodsFor:'accessing-private'!
+
+subject
+    "Return the real object for which the receiver
+     is a presentor.
+     
+     For internal usage only."
+
+    ^ self shouldNotImplement
+
+    "Created: / 20-06-2014 / 11:10:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ConstantPO methodsFor:'testing'!
+
+isSmallSenseConstantPO
+    ^ true
+! !
+
+!ConstantPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__CriticsWindow.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,507 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SimpleDialog subclass:#CriticsWindow
+	instanceVariableNames:'ruleHolder ruleRationaleAndFixesHTMLHolder rationalView fixer
+		entered codeView closeOnLeave'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface'
+!
+
+!CriticsWindow class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!CriticsWindow class methodsFor:'help specs'!
+
+flyByHelpSpec
+    "This resource specification was automatically generated
+     by the UIHelpTool of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIHelpTool may not be able to read the specification."
+
+    "
+     UIHelpTool openOnClass:SmallSense::CriticsWindow
+    "
+
+
+
+    ^ super flyByHelpSpec addPairsFrom:#(
+
+#disableRule
+'Disable this rule in the future\(for the rest of this session, unless you save the ruleset)'
+
+#browseRule
+'Open a browser on the rule'
+
+)
+! !
+
+!CriticsWindow class methodsFor:'interface specs'!
+
+windowSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::CriticsWindow andSelector:#windowSpec
+     SmallSense::CriticsWindow new openInterface:#windowSpec
+     SmallSense::CriticsWindow open
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: windowSpec
+       window: 
+      (WindowSpec
+         label: 'SmalllintRuleDetail'
+         name: 'SmalllintRuleDetail'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 563 384)
+         backgroundColor: (Color 100.0 100.0 75.0)
+         forceRecursiveBackgroundOfDefaultBackground: true
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (ActionButtonSpec
+             label: 'closeIcon'
+             name: 'Button4'
+             layout: (AlignmentOrigin 0 1 0 0 1 0)
+             visibilityChannel: notCloseOnLeave
+             hasCharacterOrientedLabel: false
+             translateLabel: true
+             model: closeRequest
+           )
+          (HTMLViewSpec
+             name: 'Rationale'
+             layout: (LayoutFrame 0 0 20 0 0 1 -65 1)
+             level: 0
+             visibilityChannel: rationaleVisibleHolder
+             hasHorizontalScrollBar: true
+             hasVerticalScrollBar: true
+             miniScrollerHorizontal: true
+             miniScrollerVertical: true
+             htmlText: ruleRationaleAndFixesHTMLHolder
+             postBuildCallback: setupHTMLView:
+           )
+          (LinkButtonSpec
+             label: 'Disable this Rule'
+             name: 'Button3'
+             layout: (LayoutFrame -1 0 -59 1 -16 1 -30 1)
+             activeHelpKey: disableRule
+             level: 0
+             translateLabel: true
+             labelChannel: disableRuleString
+             adjust: left
+             model: disableLintRule
+             keepSpaceForOSXResizeHandleH: true
+           )
+          (LinkButtonSpec
+             name: 'Button1'
+             layout: (LayoutFrame 0 0 -29 1 -16 1 0 1)
+             activeHelpKey: browseRule
+             level: 0
+             translateLabel: true
+             labelChannel: ruleNameAspect
+             adjust: left
+             model: browseLintRule
+             keepSpaceForOSXResizeHandleH: true
+           )
+          )
+        
+       )
+     )
+! !
+
+!CriticsWindow class methodsFor:'plugIn spec'!
+
+aspectSelectors
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this. If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "Return a description of exported aspects;
+     these can be connected to aspects of an embedding application
+     (if this app is embedded in a subCanvas)."
+
+    ^ #(
+        #ruleHolder
+      ).
+
+! !
+
+!CriticsWindow methodsFor:'accessing'!
+
+closeOnLeave
+    "set if used as a flyBy tooltip, which should close automatically.
+     false, if used as a modal dialog, which needs explicit close.
+     The default is false."
+
+    ^ closeOnLeave ? false
+!
+
+closeOnLeave:aBoolean
+    "set this if used as a flyBy tooltip, which should close automatically.
+     Leave false, if used as a modal dialog, which needs explicit close.
+     The default is false."
+
+    closeOnLeave := aBoolean
+!
+
+codeView
+    ^ codeView
+!
+
+codeView:aCodeView2
+    codeView := aCodeView2.
+!
+
+notCloseOnLeave:aBoolean
+    ^ self closeOnLeave not
+!
+
+rule
+
+    ^self ruleHolder value.
+
+    "Created: / 30-01-2012 / 21:45:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+rule: anRBLintRule
+
+    ^self ruleHolder value: anRBLintRule
+
+    "Created: / 30-01-2012 / 21:45:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CriticsWindow methodsFor:'actions'!
+
+browseLintRule
+    self browseLintRule:self ruleHolder value
+!
+
+browseLintRule:rule
+    |ruleClass|
+
+    rule isNil ifTrue:[^ self].
+
+    ruleClass := rule class.
+    self close.
+    UserPreferences current systemBrowserClass
+       openInClass:ruleClass selector:#rationale
+
+    "Created: / 07-09-2011 / 04:09:38 / cg"
+    "Modified: / 31-01-2012 / 11:30:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+disableLintRule
+    |rule|
+
+    rule := self ruleHolder value.
+    rule isNil ifTrue:[^ self].
+
+    RBBuiltinRuleSet rulesetBuiltinDefault reject:[:r | r class == rule class].
+    self close.
+!
+
+doQuickFix: quickFixNo
+    self closeDownViews.
+    "/ cg: why fork here?
+    "[" fixer performFix: quickFixNo "] fork".
+
+    "Created: / 16-02-2012 / 14:19:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CriticsWindow methodsFor:'aspects'!
+
+closeIcon
+    ^ ToolbarIconLibrary removeTab16x16Icon
+!
+
+disableRuleString
+
+
+    ^ ('Disable this Rule'
+        colorizeAllWith: Color blue)
+        actionForAll:[ self disableLintRule]
+!
+
+ruleHolder
+    "return/create the 'ruleHolder' value holder (automatically generated)"
+
+    ruleHolder isNil ifTrue:[
+        ruleHolder := ValueHolder with: (RBDebuggingCodeLeftInMethodsRule new)
+    ].
+    ^ ruleHolder
+
+    "Modified: / 30-01-2012 / 21:43:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+ruleHolder:something
+    "set the 'ruleHolder' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    ruleHolder notNil ifTrue:[
+	oldValue := ruleHolder value.
+	ruleHolder removeDependent:self.
+    ].
+    ruleHolder := something.
+    ruleHolder notNil ifTrue:[
+	ruleHolder addDependent:self.
+    ].
+    newValue := ruleHolder value.
+    oldValue ~~ newValue ifTrue:[
+	self update:#value with:newValue from:ruleHolder.
+    ].
+!
+
+ruleNameAspect
+
+
+    |holder|
+
+    (holder := builder bindingAt:#ruleNameAspect) isNil ifTrue:[
+        holder := BlockValue
+                    with:[:h |
+                        |text rules|
+
+                        text := ''.
+                        rules := h isComposite ifTrue:[ h rules ] ifFalse:[ { h } ].
+                        rules 
+                            do:[:each |
+                                |anchor|
+
+                                "/ h displayString , ' ' , (('[browse]' actionForAll:[ self browseLintRule]) colorizeAllWith:Color blue)
+                                anchor :=
+                                        (('Browse Rule Class (',each class name,')' "displayString")
+                                            colorizeAllWith: Color blue)
+                                                actionForAll:[ self browseLintRule:each ].
+                                text := text , anchor.
+                            ]
+                            separatedBy:[
+                                text := text , '<br>'
+                            ].
+                        text.
+                    ]
+                    argument: self ruleHolder.
+        builder aspectAt:#ruleNameAspect put:holder.
+    ].
+    ^ holder.
+
+    "Modified: / 05-02-2010 / 12:51:30 / Jan Vrany "
+    "Modified: / 07-09-2011 / 04:54:24 / cg"
+!
+
+ruleRationaleAndFixesHTMLHolder
+    "return/create the 'ruleRationaleAndFixesHTMLHolder' value holder (automatically generated)"
+
+    ruleRationaleAndFixesHTMLHolder isNil ifTrue:[
+        ruleRationaleAndFixesHTMLHolder := ValueHolder new.
+    ].
+    ^ ruleRationaleAndFixesHTMLHolder
+
+    "Modified (format): / 01-02-2012 / 10:57:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CriticsWindow methodsFor:'change & update'!
+
+generateHTMLForRule: rule on: stream
+    | fixes |    
+     stream 
+        nextPutAll: rule name; 
+        nextPutAll:'<P>';  
+        nextPutLine: rule rationale.
+
+    "/ Generate fixes...
+    rule fixes: fixer.
+    fixes := fixer fixesForRule: rule.
+    fixes isEmptyOrNil ifTrue:[ ^ self ].
+
+    stream nextPutAll: '<p>'.
+    fixes size > 1 ifTrue:[
+        stream nextPutAll: '<br>'.
+        stream nextPutLine: 'Possible fixes:'.
+    ].
+    stream nextPutLine:'<ul indent="0">'.
+    fixes withIndexDo:[:fix :index|
+        stream
+            nextPutAll:'<li><a action="doit: self doQuickFix:';
+            nextPutAll: index printString;
+            nextPutAll:'">';
+            nextPutAll: fix label;
+            nextPutAll:'</a></li>'.
+    ].
+    stream nextPutLine:'</ul>'.
+
+    "Created: / 15-12-2014 / 16:49:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 18:17:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+update:something with:aParameter from:changedObject
+    "Invoked when an object that I depend upon sends a change notification."
+
+    changedObject == ruleHolder ifTrue:[
+         self updateRationaleAndFixes.
+         ^ self.
+    ].
+    super update:something with:aParameter from:changedObject
+
+    "Modified: / 01-02-2012 / 10:56:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateRationaleAndFixes
+    | rule html |
+
+    rule := self ruleHolder value.
+    rule isNil ifTrue:[
+        fixer := nil.
+        html :=  'No rule...'.
+    ] ifFalse:[
+        fixer := SmalltalkQuickFixer forView: codeView.
+
+        html := String streamContents:[:s|
+            rule isComposite ifFalse:[ 
+                self generateHTMLForRule: rule on: s.
+            ] ifTrue:[ 
+                rule flatten 
+                    do:[:each | self generateHTMLForRule: each on: s. ]
+                    separatedBy:[ s nextPutLine: '<hr>' ]
+            ]
+        ].
+    ].
+
+    self ruleRationaleAndFixesHTMLHolder value: html
+
+    "Created: / 01-02-2012 / 10:56:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 18:18:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CriticsWindow methodsFor:'event processing'!
+
+processEvent: anEvent
+
+    anEvent isKeyReleaseEvent ifTrue:[
+        anEvent key == #Escape ifTrue:[
+            self closeRequest. "/ closeDownViews.
+            ^true.
+        ].
+    ].
+
+    "/ cg: if this is a modal dialog - do not exit on leave.
+    "/ if used as a flyBy, set the closeOnLeave flag.
+    self closeOnLeave ifTrue:[
+        anEvent isPointerLeaveEvent ifTrue:[
+            anEvent view == self window ifTrue:[
+                self closeRequest. "/ closeDownViews.
+                ^true.
+            ]
+        ].
+    ].
+
+    ^false
+
+    "Created: / 16-02-2012 / 14:09:33 / Jan Vrany "
+    "Modified (format): / 31-03-2014 / 16:53:41 / Jan Vrany "
+! !
+
+!CriticsWindow methodsFor:'hooks'!
+
+postBuildWith: aBuilder
+    super postBuildWith:aBuilder.
+
+    aBuilder window allViewBackground:(aBuilder window viewBackground).
+
+    entered := false.
+    self updateRationaleAndFixes.
+    aBuilder window beSlave.
+
+    "Created: / 03-04-2011 / 10:45:10 / Jan Vrany "
+    "Modified: / 16-02-2012 / 14:14:07 / Jan Vrany "
+!
+
+postOpenWith: bldr
+    super postOpenWith: bldr.
+    self windowGroup addPreEventHook: self.
+
+    "Created: / 16-02-2012 / 14:09:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CriticsWindow methodsFor:'initialization'!
+
+setupHTMLView:aView
+    rationalView := aView.
+    aView painter
+        leftMargin:20;
+        topMargin:5.
+
+    "Created: / 04-08-2011 / 18:00:36 / cg"
+! !
+
+!CriticsWindow class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/smallsense/SmallSense__CriticsWindow.st,v 1.2 2015-01-27 11:42:45 cg Exp $'
+!
+
+version_CVS
+    ^ '$Path: stx/goodies/smallsense/SmallSense__CriticsWindow.st, Version: 1.0, User: cg, Time: 2015-01-27T12:43:08.573+01$'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id: SmallSense__CriticsWindow.st,v 1.2 2015-01-27 11:42:45 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__EditService.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,241 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Tools::CodeViewService subclass:#EditService
+	instanceVariableNames:'environment support'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Services'
+!
+
+!EditService class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!EditService class methodsFor:'initialization'!
+
+initialize
+    "
+     | map |
+     map := Screen current keyboardMap.
+     map bindValue:#CodeCompletion to: #'Ctrl '.
+     map bindValue:#CodeCompletion to: #'Ctrlspace'.
+    "
+
+    Smalltalk addStartBlock:[
+        Screen current notNil ifTrue:[
+            | map |
+            map := Screen current keyboardMap.
+            (map keyAtValue:#CodeCompletion) isNil ifTrue:[
+                map bindValue:#CodeCompletion to: #'Ctrl '.
+                map bindValue:#CodeCompletion to: #'Ctrlspace'.
+            ].
+       ]
+    ]
+
+    "Created: / 17-09-2013 / 15:23:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditService class methodsFor:'accessing'!
+
+label
+    "Answers a short label - for UI"
+
+    ^'SmallSense - Edit Support'
+
+    "Created: / 27-07-2013 / 22:35:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditService class methodsFor:'testing'!
+
+isAvailable
+
+    ^false
+
+    "Created: / 28-11-2014 / 15:41:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isAvailableFor: applicationClass
+
+    "Returns true if given service may be used in
+     given application class."
+
+    ^false
+
+    "Created: / 28-11-2014 / 15:41:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditService methodsFor:'accessing'!
+
+environment
+    "Return an system environment for completion."
+
+    ^ environment ? Smalltalk
+
+    "Modified: / 13-05-2014 / 12:02:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+environment:aSystemEnvironment
+    "Sets an envirronment for completion. Only classes and/or methods in
+     the environment are offered for completion"
+    environment := aSystemEnvironment.
+
+    "Modified (comment): / 13-05-2014 / 11:55:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+support
+    ^ support
+! !
+
+!EditService methodsFor:'accessing-views'!
+
+codeView
+    ^ codeView
+!
+
+gutterView
+    ^ gutterView
+!
+
+textView
+    ^ textView
+! !
+
+!EditService methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+    "Invoked when an object that I depend upon sends a change notification."
+
+    changedObject == codeView ifTrue:[
+        (#(methodHolder classHolder languageHolder) includes: something) ifTrue:[
+            aParameter key removeDependent: self.
+            aParameter value addDependent: self.                         
+        ].
+    ].
+
+    (changedObject == codeView languageHolder 
+        or:[changedObject == codeView classHolder
+        or:[changedObject == codeView methodHolder]]) ifTrue:[
+        self updateSupport.
+        ^self.
+    ].
+
+    super update:something with:aParameter from:changedObject
+
+    "Modified: / 16-09-2013 / 16:36:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSupport
+    | lang |
+
+    support language ~~ (lang := codeView language) ifTrue:[
+        self updateSupport: (EditSupport forLanguage: lang).
+    ].
+
+    "Created: / 16-09-2013 / 16:31:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-05-2015 / 21:52:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSupport: anEditSupport
+    support := anEditSupport.
+    support initializeForService: self.
+
+    "Created: / 13-05-2014 / 14:49:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditService methodsFor:'event handling'!
+
+keyPress: key x:x y:y in: view
+
+    "Handles an event in given view (a subview of codeView).
+     If the method returns true, the event will not be processed
+     by the view."
+
+    ^ support notNil 
+        ifTrue:[support keyPress: key x:x y:y in: view]
+        ifFalse:[false]
+
+    "Created: / 07-03-2010 / 09:36:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-05-2015 / 00:00:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditService methodsFor:'registering'!
+
+registerIn: aCodeView
+    UserPreferences current smallSenseEnabled ifTrue:[
+        super registerIn: aCodeView.
+        aCodeView languageHolder addDependent: self.
+        aCodeView classHolder    addDependent: self.
+        aCodeView methodHolder   addDependent: self.
+        support := EditSupport forLanguage: aCodeView language.
+        support initializeForService: self.
+    ] ifFalse:[ 
+        "/ If not enabled, remove itself from set of services,
+        "/ see Tools::CodeView2>>registerService:
+        "/ Bad API, has to be fixed in CodeView2...
+        aCodeView services remove: self ifAbsent:[ ]
+    ].
+
+    "Created: / 24-07-2013 / 23:13:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-06-2014 / 14:15:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+unregister
+    "Uninstall myself from my codeView"
+
+    codeView languageHolder removeDependent: self.
+    codeView classHolder    removeDependent: self.
+    codeView methodHolder   removeDependent: self.
+    super unregister
+
+    "Created: / 24-07-2013 / 23:14:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-06-2014 / 14:17:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditService class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
+
+EditService initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__EditSupport.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,539 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#EditSupport
+	instanceVariableNames:'textView backspaceIsUndo completionController
+		completionEnvironment snippets ignoreKeystrokes
+		ignoreKeystrokesPosition ignoreKeystrokesStartLine
+		ignoreKeystrokesStartCol electricInsertSuppressed'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Services'
+!
+
+!EditSupport class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!EditSupport class methodsFor:'instance creation'!
+
+forLanguage: aProgrammingLanguage
+    aProgrammingLanguage notNil ifTrue:[
+        aProgrammingLanguage isSmalltalk ifTrue:[
+            ^ SmalltalkEditSupport new
+        ].
+        (aProgrammingLanguage askFor: #isJava) ifTrue:[    
+            ^ JavaEditSupport new
+        ].
+        (aProgrammingLanguage askFor: #isGroovy) ifTrue:[    
+            ^ GroovyEditSupport new
+        ]  
+    ].
+
+    ^GenericEditSupport new.
+
+    "Created: / 24-07-2013 / 23:20:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 08:41:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport methodsFor:'accessing'!
+
+electricInsertSuppressed
+    ^ electricInsertSuppressed
+!
+
+environment
+    ^ completionEnvironment ? Smalltalk
+
+    "Created: / 15-05-2014 / 16:44:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:58:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+language
+    ^ self subclassResponsibility.
+
+    "Created: / 24-07-2013 / 23:44:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+textView
+    ^ textView
+
+    "Created: / 03-02-2014 / 23:28:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport methodsFor:'accessing-classes'!
+
+completionControllerClass
+    "raise an error: this method should be implemented (TODO)"
+
+    ^ CompletionController
+
+    "Created: / 13-05-2014 / 16:13:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completionEngineClass
+    "Returns a code completion engine class or nil, of 
+     no completion is supported"
+
+    ^ nil
+
+    "Created: / 03-10-2013 / 17:43:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+scannerClass
+    "Returns a class to use for scanning lines. If nil, scanning is
+     not supported and scanLine* methods will return an empty array."
+
+    ^ nil
+
+    "Created: / 22-10-2013 / 00:33:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport methodsFor:'editing'!
+
+electricDeleteCharacterAtCol: col 
+    textView deleteCharAtLine: textView cursorLine col: col
+
+    "Created: / 22-01-2014 / 21:17:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricDeleteCharacterAtLine:line col: col 
+    textView deleteCharAtLine: line col: col
+
+    "Created: / 22-01-2014 / 21:16:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricDo:aBlock 
+    textView completionSupport notNil ifTrue:[
+        (textView completionSupport)
+            stopCompletionProcess;
+            closeCompletionView.
+    ].
+    textView hasSelection ifTrue:[
+        textView undoableDo:[ textView deleteSelection ].
+    ].
+    textView undoableDo:[ aBlock value. ].
+    backspaceIsUndo := true.
+
+    "Created: / 17-09-2013 / 23:15:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 22-10-2013 / 03:15:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsert:text 
+    self electricInsert:text advanceCursorBy:nil.
+
+    "Created: / 22-10-2013 / 11:08:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsert:stringOrLines advanceCursorBy:offsetOrNil 
+    ^ self 
+            electricInsert:stringOrLines
+            advanceCursorBy:offsetOrNil
+            ignoreKeystrokes:nil
+
+    "Created: / 22-10-2013 / 11:56:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-01-2014 / 20:29:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsert:stringOrLines advanceCursorBy:offsetOrNil ignoreKeystrokes:ignoreKeystrokeSequence 
+    "Insert given stringOrLines. If offsetOrNil is not nil, then
+     move cursor by `offsetOrNil` after the **begining** of
+     inserted text. If `ignoreKeystrokeSequence` is not nil and not empty, then if
+     subsequent key strokes are ignored (i.e, does nothing) if matches
+     the given sequence. This is used to avoid duplication if user is not
+     aware of electric insertion and types whole text that has been
+     (electrically) inserted).
+
+     `stringOrLines` could be either string or collection of strings (lines)
+     `offsetOrNil` could be either integer (cursor is then advanced by
+            offsetOrNil characters after **begining** of inserted text)
+            or point (x,y, cursor is then advanced by x lines after current
+            line and by y characters after beggining of the inserted text
+            (if x == 0) or at set at column y (if x ~~ 0)
+     `ignoreKeystrokeSequence` a sequenceable collection of keys (in a form
+            as passed to #keyPress:x:y: method."
+    
+    | lineOffset colOffset oldCursorLine oldCursorCol newCursorLine newCursorCol advanceCursor |
+
+    advanceCursor := false.
+    ignoreKeystrokeSequence notNil ifTrue:[ 
+        oldCursorLine := textView cursorLine.
+        oldCursorCol := textView cursorCol.
+    ].
+    offsetOrNil notNil ifTrue:[
+        lineOffset := offsetOrNil isPoint ifTrue:[
+                offsetOrNil x
+            ] ifFalse:[ 0 ].
+        colOffset := offsetOrNil isPoint ifTrue:[
+                offsetOrNil y
+            ] ifFalse:[
+                offsetOrNil
+            ].
+        newCursorLine := textView cursorLine + lineOffset.
+        newCursorCol := (lineOffset == 0 
+                ifTrue:[ textView cursorCol ]
+                ifFalse:[ 0 ]) + colOffset.
+        advanceCursor := true.
+    ].
+    self 
+        electricDo:[
+            stringOrLines isString ifTrue:[
+                "/ Simple strin
+                textView insertStringAtCursor:stringOrLines.
+            ] ifFalse:[
+                "/ C
+                textView insertLines:stringOrLines withCR:false.
+            ].
+            advanceCursor ifTrue:[
+                (textView cursorLine ~~ newCursorLine 
+                    or:[ textView cursorCol ~~ newCursorCol ]) 
+                        ifTrue:[ textView cursorLine:newCursorLine col:newCursorCol. ].
+            ].
+        ].
+    ignoreKeystrokeSequence notEmptyOrNil ifTrue:[
+        ignoreKeystrokes := ignoreKeystrokeSequence.
+        ignoreKeystrokesPosition := 1.
+        stringOrLines isString ifTrue:[ 
+            ignoreKeystrokesStartLine := oldCursorLine.
+            ignoreKeystrokesStartCol := oldCursorCol + (stringOrLines size - ignoreKeystrokeSequence size)
+        ].
+    ].
+
+    "Created: / 19-01-2014 / 20:29:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 06:29:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsert:text ignoreKeystrokes:ignore 
+    self 
+        electricInsert:text
+        advanceCursorBy:nil
+        ignoreKeystrokes:ignore
+
+    "Created: / 21-01-2014 / 23:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsertBlockOpenedBy:openText closedBy:closeText 
+    | indent  lines  autoIndent |
+
+    textView completionSupport notNil ifTrue:[
+        (textView completionSupport)
+            stopCompletionProcess;
+            closeCompletionView.
+    ].
+    indent := self indentAtCursorLine.
+    autoIndent := textView autoIndent.
+    textView autoIndent:false.
+    [
+        textView 
+            undoableDo:[
+                lines := Array 
+                        with:openText ? ''
+                        with:''
+                        with:((String new:indent withAll:Character space) , closeText).
+                self electricInsert:lines advanceCursorBy:1 @ (indent + 5)
+            ].
+    ] ensure:[ textView autoIndent:autoIndent ].
+
+    "Created: / 25-07-2013 / 10:41:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 22-01-2014 / 21:20:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsertSnippet
+    ^ false
+
+    "Created: / 22-10-2013 / 01:54:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport methodsFor:'event handling'!
+
+keyPress: key x:x y:y in: view
+    "Handles an event in given view (a subview of codeView).
+     If the method returns true, the event will not be processed
+     by the view.
+
+     IMPORTANT: Never ever call `^ super keyPress: key x:x y:y in: view`,
+     as keyPresIgnore... advances position and calling keyPressIgnore here
+     and calling super would advance it twice!!
+     "
+
+    view ~~ textView ifTrue:[ ^ false ].
+
+    (self keyPressIgnored: key) ifTrue:[
+        ^ true.
+    ].
+
+    UserPreferences current smallSenseElectricEditSupportEnabled ifFalse:[ ^ false ].
+
+    key == Character space ifTrue:[
+        ^ self electricInsertSnippet
+    ].
+
+    ^false
+
+    "Created: / 24-07-2013 / 23:31:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-05-2015 / 00:01:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressIgnored
+    "Advance position in keyPressIgnore buffer. Return true if position has been edvanced, false othwrwise"
+    ignoreKeystrokes notNil ifTrue:[
+        ignoreKeystrokesPosition := ignoreKeystrokesPosition + 1.
+        ignoreKeystrokesPosition > ignoreKeystrokes size ifTrue:[
+            "/ Nil out instvars if there's no more keys to ignore.
+            ignoreKeystrokes := ignoreKeystrokesPosition := nil.
+        ].
+        ^ true.
+    ].
+    ^ false.
+
+    "Created: / 11-08-2014 / 14:56:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressIgnored: key
+    ignoreKeystrokes notNil ifTrue:[
+        (ignoreKeystrokes at: ignoreKeystrokesPosition) == key ifTrue:[
+            "/ Key stroke should be ignored...
+            ignoreKeystrokesPosition := ignoreKeystrokesPosition + 1.
+            ignoreKeystrokesPosition > ignoreKeystrokes size ifTrue:[
+                "/ Nil out instvars if there's no more keys to ignore.
+                ignoreKeystrokes := ignoreKeystrokesPosition := ignoreKeystrokesStartLine := ignoreKeystrokesStartCol := nil.
+            ].
+            ^ true.
+        ] ifFalse:[
+            "/ User continued typing something else. If it *seems* to be
+            "/ thet user wanted something else, then delete the rest, i.e.,
+            "/ user typed:
+            "/ 
+            "/ th
+            "/ 
+            "/ then the machinery completed `isContext` so the text is
+            "/ 
+            "/ thisContext
+            "/ 
+            "/ and user continues typing `isValue`. In that case user wanted to
+            "/ `thisValue` instead of `thisContext` - in this case remove the rest
+            "/ of what has been completed.
+            "/ 
+            "/ However, imagine following case: user types `th` so it completes
+            "/ `thisContext` like in previous case. Now the user types . (dot).
+            "/ to end the statement. In this case, perhaps `thisContext` is what
+            "/ he needs.
+            "/ 
+            "/ How to tell between those two cases?
+            "/ 
+            "/ Currently, a simple heuristics is used - if the typed character can be
+            "/ part of an identifier, then it's the former case, otherwise assume
+            "/ the latter. We'll see.
+            "/
+            (key isCharacter and:[key isLetterOrDigit or:[key == $_]]) ifTrue:[ 
+                ignoreKeystrokesStartLine notNil ifTrue:[  
+                    textView deleteCharsAtLine: ignoreKeystrokesStartLine fromCol: ignoreKeystrokesStartCol + ignoreKeystrokesPosition - 1 toCol: ignoreKeystrokesStartCol + ignoreKeystrokes size - 1.
+                    textView setCursorLine: ignoreKeystrokesStartLine.
+                    textView setCursorCol: ignoreKeystrokesStartCol + ignoreKeystrokesPosition - (ignoreKeystrokesPosition > 1 ifTrue:[ 1 ] ifFalse:[ 0 ]).
+                ].
+            ].
+            ignoreKeystrokes := ignoreKeystrokesPosition := ignoreKeystrokesStartLine := ignoreKeystrokesStartCol := nil.
+            ^ false.
+        ].
+    ].
+    ^ false.
+
+    "Created: / 20-01-2014 / 09:11:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 05-03-2015 / 12:47:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 06-03-2015 / 07:08:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressSpace
+    ^ self electricInsertSnippet
+
+    "Created: / 22-10-2013 / 01:43:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport methodsFor:'initialization'!
+
+initializeCompletion
+    | controller |
+
+    UserPreferences current smallSenseCompletionEnabled ifTrue:[
+        self completionEngineClass notNil ifTrue:[
+            controller := self completionControllerClass for: textView.
+            controller support: self.
+            textView completionSupport: controller.
+        ].
+    ].
+
+    "Created: / 18-05-2014 / 12:40:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:44:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+initializeForService:anEditService
+    completionEnvironment := anEditService environment.
+    self initializeForTextView: anEditService textView.
+
+    "Created: / 27-09-2013 / 13:19:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:16:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+initializeForTextView: anEditTextView
+    textView := anEditTextView.
+    backspaceIsUndo := false.
+    electricInsertSuppressed := false.
+    self initializeCompletion.
+
+    "Created: / 12-02-2015 / 00:16:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-03-2015 / 17:14:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport methodsFor:'private'!
+
+indentAtCursorLine
+    | line |
+
+    line := textView listAt: textView cursorLine.
+    ^ line isNil ifTrue:[
+        (textView cursorCol - 1) max: 0.
+    ] ifFalse:[
+        (line indexOfNonSeparator - 1) max: 0.
+    ]
+
+    "Created: / 25-07-2013 / 00:13:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:44:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+wordBeforeCursor
+    ^ self wordBeforeCursorConsisitingOfCharactersMatching: [:c | c isAlphaNumeric ].
+
+    "Created: / 27-09-2013 / 15:53:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-03-2014 / 23:03:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+wordBeforeCursorConsisitingOfCharactersMatching: characterMatchBlock
+    |  currentLine wordStart wordEnd |
+    currentLine := textView list at: textView cursorLine ifAbsent:[ ^ '' ].
+    currentLine isNil ifTrue:[ ^ '' ].
+    wordEnd := textView cursorCol - 1.
+    wordEnd > currentLine size ifTrue:[ ^ '' ].
+    wordEnd ~~ 0 ifTrue:[
+        wordStart := wordEnd.
+        [ wordStart > 0 and:[characterMatchBlock value:(currentLine at: wordStart) ] ] whileTrue:[
+            wordStart := wordStart - 1.
+        ].
+        wordStart := wordStart + 1.
+        wordStart <= wordEnd ifTrue:[
+            ^ currentLine copyFrom: wordStart to: wordEnd.
+        ].
+    ].
+    ^ ''
+
+    "Created: / 31-03-2014 / 23:02:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-06-2014 / 07:27:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport methodsFor:'private-scanning'!
+
+scanLineAt: lineNumber 
+    "Scans line at given line number.
+
+     Returns and array of tokens, **excluding** EOF. Each token is represented
+     by four subsequent items in the array: token type, token value, start position, end position.
+     Thus, returned array size is always multiple of 4."
+
+    ^ self scanLineAt: lineNumber using: self scannerClass
+
+    "Created: / 22-10-2013 / 00:34:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+scanLineAt: lineNumber using: scannerClass
+    "Scans line at given line number using given scanner class.
+
+     Returns and array of tokens, **excluding** EOF. Each token is represented
+     by four subsequent items in the array: token type, token value, start position, end position.
+     Thus, returned array size is always multiple of 4."
+
+    | line scanner token tokenLastEndPosition |
+
+    scannerClass isNil ifTrue:[ ^ #() ].
+    line := textView listAt: textView cursorLine.
+    line isNil ifTrue:[ ^ #() ].
+    scanner := scannerClass for: line string.
+    tokenLastEndPosition := 0.
+    ^ OrderedCollection streamContents:[:tokens |
+        [
+            [ token := scanner nextToken.token ~~ #EOF ] whileTrue:[
+                tokens 
+                    nextPut: token; 
+                    nextPut: (scanner tokenName notNil ifTrue:[scanner tokenName] ifFalse:[ scanner tokenValue printString ]); 
+                    nextPut: scanner tokenStartPosition;
+                    nextPut: (tokenLastEndPosition := scanner tokenEndPosition).
+            ].
+        ] on: Error do:[
+                tokens 
+                    nextPut: 'Error'; 
+                    nextPut: (line copyFrom: tokenLastEndPosition + 1 to: line size); 
+                    nextPut: tokenLastEndPosition + 1;
+                    nextPut: line size.
+        ].
+    ].
+
+    "Created: / 22-10-2013 / 00:31:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:43:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+scanLineAtCursor
+    "Scans current cursor line.
+
+     Returns and array of tokens, **excluding** EOF. Each token is represented
+     by four subsequent items in the array: token type, token value, start position, end position.
+     Thus, returned array size is always multiple of 4."
+
+    ^ self scanLineAt: textView cursorLine using: self scannerClass
+
+    "Created: / 22-10-2013 / 00:34:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:44:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupport class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__EditSupportTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractTestCase subclass:#EditSupportTests
+	instanceVariableNames:'codeView codeViewInteractor editService editSupport'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!EditSupportTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!EditSupportTests methodsFor:'accessing-classes'!
+
+editSupportClass
+    self subclassResponsibility
+
+    "Created: / 23-07-2014 / 07:15:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupportTests methodsFor:'running'!
+
+setUp
+    | topView |
+
+    super setUp.
+
+    Smalltalk loadPackage: 'stx:goodies/sunitext/ui'.
+
+    topView := StandardSystemView new.
+    topView extent: 320 @ 200.
+    topView label: self printString.
+    codeView := Tools::CodeView2 origin: 0.0@0.0 extent: 1.0@1.0 in: topView.
+    codeViewInteractor := codeView interactor.
+
+    editService := EditService new.
+    editSupport := self editSupportClass new.
+    codeView services: (Array with: editService).
+    codeView language: editSupport language.
+    editService updateSupport: editSupport.
+
+    topView open.
+    topView waitUntilVisible.
+
+    "Created: / 23-07-2014 / 07:15:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 04-03-2015 / 09:42:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+tearDown
+
+    editService := nil.
+    editSupport := nil.
+    codeView topView destroy.
+
+    super tearDown
+
+    "Created: / 23-07-2014 / 07:17:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 09:43:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditSupportTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__FinderTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,9744 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+TestCase subclass:#FinderTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests-Obsolete'
+!
+
+!FinderTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!FinderTests methodsFor:'BeforeStatementTests'!
+
+testBeforeStatement1
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:2
+                position:21
+                tree:collector tree.
+    self assert:(foundNode beforeStatement isNil).
+
+    "Created: / 02-03-2011 / 20:02:25 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement10
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:21
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 20:16:47 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement11
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:23
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 21:13:28 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement12
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:24
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 21:13:46 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement13
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:25
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 21:20:04 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement14
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:26
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+    self assert:(foundNode beforeStatement name = 'u').
+
+    "Created: / 02-03-2011 / 21:20:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement15
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:31
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+    self assert:(foundNode beforeStatement name = 'u').
+
+    "Created: / 02-03-2011 / 21:37:15 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement16
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:32
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 21:37:39 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement17
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:33
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 21:42:47 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement18
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:35
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 21:44:49 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement19
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:36
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 21:45:11 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement2
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:2
+                position:24
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 20:02:40 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement20
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:38
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 21:59:58 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement21
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:40
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 22:00:10 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement22
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:21
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 22:13:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement23
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:22
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 22:13:51 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement24
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:23
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 22:14:12 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement25
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:29
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 22:14:52 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement26
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:30
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 22:18:54 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement27
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:31
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 22:31:14 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement28
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:32
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 22:37:05 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement29
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:33
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 22:37:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement3
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:2
+                position:26
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 20:07:16 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement30
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:40
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 22:37:57 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement31
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:21
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 22:43:37 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement32
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:22
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 22:44:37 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement33
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:23
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 22:44:48 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement34
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:24
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 22:51:21 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement35
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:29
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 22:51:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement36
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:30
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 22:51:50 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement37
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:31
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 22:52:09 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement38
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:33
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isConstant).
+
+    "Created: / 02-03-2011 / 22:52:39 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement39
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:35
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 22:57:40 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement4
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:2
+                position:27
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 20:07:32 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement40
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:37
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 22:58:16 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement41
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:21
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 22:58:46 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement42
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:26
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelf).
+
+    "Created: / 02-03-2011 / 22:59:09 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement43
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:45
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 23:00:06 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement44
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:49
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:01:40 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 08-04-2011 / 00:05:41 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement45
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:51
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:02:49 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement46
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:55
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 23:03:14 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement47
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:60
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 23:04:14 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement48
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:63
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:04:38 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement49
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:65
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:14:59 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement5
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:21
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 20:07:50 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement50
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:68
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 23:15:18 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement51
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:73
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 23:15:34 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement52
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:75
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 23:16:16 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement53
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:77
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 23:16:32 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement54
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:83
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:16:56 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement55
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:17:32 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement56
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:28
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 23:43:04 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement57
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:41
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 23:43:29 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement58
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:44
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 23:44:12 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement59
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:9
+                position:42
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 23:44:49 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement6
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:22
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 20:15:09 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement60
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:22
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 23:46:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement61
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:27
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 23:46:50 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement62
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:45
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:47:36 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement63
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:35
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 23:57:56 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement64
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:51
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isBlock).
+
+    "Created: / 02-03-2011 / 23:58:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement65
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u .
+                    d  floor: 3 b:u .
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:  c dd:d  .
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:61
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 23:59:03 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement7
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:23
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 20:15:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement8
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:24
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 20:15:55 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBeforeStatement9
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:27
+                tree:collector tree.
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 02-03-2011 / 20:16:10 / Jakub <zelenja7@fel.cvut.cz>"
+! !
+
+!FinderTests methodsFor:'FinderTests'!
+
+testFinder1
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u .
+                    d floor:3 b:u.
+                     self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ]     .
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:1
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode position) = 1).
+    self assert:((foundNode line) = 3).
+    self assert:(foundNode node isNil).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 22-02-2011 / 14:40:34 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 27-02-2011 / 23:36:22 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder10
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3 .
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:24
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 5).
+    self assert:((foundNode position) = 24).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:46:15 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 25-02-2011 / 17:13:25 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder100
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:22
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 22).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:29:35 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder101
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 18).
+    self assert:(foundNode node charIndex = 23).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:44:06 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder102
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:24
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 24).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 18).
+    self assert:(foundNode node charIndex = 23).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:45:17 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder103
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 25).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 18.
+    self assert:(foundNode node selectorsPosition = 24).
+    self assert:(foundNode node selectors asString = '==').
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:45:32 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder104
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol or: [u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:26
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 26).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 18.
+    self assert:(foundNode node selectorsPosition = 24).
+    self assert:(foundNode node selectors asString = '==').
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:48:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder105
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol or: [u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:27
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 27).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node value = #Symbol).
+    self assert:(foundNode node line = 18).
+    self assert:(foundNode node charIndex = 27).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:48:41 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder106
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:34
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 34).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node value = #Symbol).
+    self assert:(foundNode node line = 18).
+    self assert:(foundNode node charIndex = 27).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:49:43 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder107
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:35
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 35).
+    self assert:(foundNode node isMessage).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:52:10 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder108
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:36
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 36).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 18.
+    self assert:((foundNode node selectorsPosition at:1) = 36).
+    self assert:(foundNode node selectors asString = 'or:').
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:53:20 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder109
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:39
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 39).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 18.
+    self assert:((foundNode node selectorsPosition at:1) = 36).
+    self assert:(foundNode node selectors asString = 'or:').
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:55:26 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder11
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:29
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 5).
+    self assert:((foundNode position) = 29).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:47:36 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 28-02-2011 / 19:52:00 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder110
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:40
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 40).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 18.
+    self assert:((foundNode node selectorsPosition at:1) = 36).
+    self assert:(foundNode node selectors asString = 'or:').
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:56:26 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder111
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:19
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 19).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode node isMessage).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:57:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder112
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:42
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 42).
+    self assert:(foundNode node isMessage).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:39:49 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder113
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3  ]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:19
+                position:25
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 19).
+    self assert:((foundNode position) = 25).
+    self assert:(foundNode node isMessage).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:46:28 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder114
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3  ]  ]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:19
+                position:27
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 19).
+    self assert:((foundNode position) = 27).
+    self assert:(foundNode node isBlock).
+    self assert:(foundNode node lineNumber = 18).
+    self assert:(foundNode node endLineNumber = 19).
+    self assert:(foundNode node charStartIndex = 40).
+    self assert:(foundNode node charEndIndex = 26).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:47:30 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder115
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3  ]  ]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:19
+                position:29
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 19).
+    self assert:((foundNode position) = 29).
+    self assert:(foundNode node isBlock).
+    self assert:(foundNode node lineNumber = 18).
+    self assert:(foundNode node endLineNumber = 19).
+    self assert:(foundNode node charStartIndex = 40).
+    self assert:(foundNode node charEndIndex = 26).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:48:17 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder116
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:19
+                position:30
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 19).
+    self assert:((foundNode position) = 30).
+    self assert:(foundNode node isBlock).
+    self assert:(foundNode node lineNumber = 18).
+    self assert:(foundNode node endLineNumber = 19).
+    self assert:(foundNode node charStartIndex = 21).
+    self assert:(foundNode node charEndIndex = 29).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:48:46 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder117
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:23
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 23).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'dd').
+    self assert:(foundNode node line = 23).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:54:03 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder118
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+
+.
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:27
+                position:23
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 27).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isBlock).
+    self assert:(foundNode node lineNumber = 26).
+    self assert:(foundNode node endLineNumber = 27).
+    self assert:(foundNode node charStartIndex = 27).
+    self assert:(foundNode node charEndIndex = 21).
+    self assert:((foundNode node) ~= (foundNode statement)).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:56:23 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder119
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [
+                    u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+
+.
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:26
+                position:29
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 26).
+    self assert:((foundNode position) = 29).
+    self assert:(foundNode node isMessage).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 19:59:44 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder12
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 6).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:48:20 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder13
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 21).
+    self assert:((foundNode line) = 6).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'b').
+    self assert:(foundNode node line = 6).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:48:29 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder14
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:22
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 22).
+    self assert:((foundNode line) = 6).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'b').
+    self assert:(foundNode node line = 6).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:49:39 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder15
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 23).
+    self assert:((foundNode line) = 6).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:49:48 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder16
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:24
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 24).
+    self assert:((foundNode line) = 6).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 6).
+    self assert:(foundNode node charIndex = 24).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:50:39 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder17
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 25).
+    self assert:((foundNode line) = 6).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 6).
+    self assert:(foundNode node charIndex = 24).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:51:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder18
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:6
+                position:26
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 6).
+    self assert:((foundNode position) = 26).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:51:45 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 25-02-2011 / 17:31:30 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder19
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 7).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:52:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder2
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 21).
+    self assert:((foundNode line) = 3).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 3).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:34:28 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder20
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 21).
+    self assert:((foundNode line) = 7).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node line = 7).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode node name = 'c').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder21
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:22
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 22).
+    self assert:((foundNode line) = 7).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node line = 7).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode node name = 'c').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder22
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 7).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 14:30:37 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder23
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:24
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 24).
+    self assert:((foundNode line) = 7).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node line = 7).
+    self assert:(foundNode node charIndex = 24).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder24
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 25).
+    self assert:((foundNode line) = 7).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node line = 7).
+    self assert:(foundNode node charIndex = 24).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder26
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:7
+                position:26
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode position) = 26).
+    self assert:((foundNode line) = 7).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node line = 7).
+    self assert:(foundNode node charIndex = 24).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder27
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:1
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode position) = 1).
+    self assert:((foundNode line) = 8).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node line = 7).
+    self assert:(foundNode node charIndex = 24).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder28
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 25).
+    self assert:((foundNode line) = 8).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 8.
+    self assert:(foundNode node selectorsPosition = 25).
+    self assert:(foundNode node selectors asString = 'floor').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder29
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:30
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 30).
+    self assert:((foundNode line) = 8).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 8.
+    self assert:(foundNode node selectorsPosition = 25).
+    self assert:(foundNode node selectors asString = 'floor').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder3
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:22
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 22).
+    self assert:((foundNode line) = 3).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node line = 3).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:36:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder30
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:8
+                position:32
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode position) = 32).
+    self assert:((foundNode line) = 8).
+    self assert:(foundNode node isUnaryMessage).
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder31
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:9
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 25).
+    self assert:((foundNode line) = 9).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node lines size = 1).
+    self assert:(foundNode node lines at:1) = 9.
+    self assert:(foundNode node selectorsPosition = 25).
+    self assert:(foundNode node selectors asString = 'aa').
+    self assert:(foundNode statement isAssignment)
+!
+
+testFinder32
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:9
+                position:28
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 9).
+    self assert:((foundNode position) = 28).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 14:41:23 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 25-02-2011 / 17:40:06 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder33
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:9
+                position:30
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 9).
+    self assert:((foundNode position) = 30).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 14:32:35 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder34
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:9
+                position:31
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 9).
+    self assert:((foundNode position) = 31).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:33:08 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder35
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:34:07 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder36
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'd').
+    self assert:(foundNode node line = 10).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:34:41 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder37
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:22
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 22).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'd').
+    self assert:(foundNode node line = 10).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:36:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder38
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:23
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'd').
+    self assert:(foundNode node line = 10).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:37:09 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder39
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:24
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 24).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 24).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 10).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:37:53 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:08:24 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder4
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 23).
+    self assert:((foundNode line) = 3).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:39:04 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder40
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:27
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 27).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 24).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 10).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:43:08 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:08:34 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder41
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:29
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 29).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 24).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 10).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:43:42 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:08:39 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder42
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:30
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 30).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 24).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 10).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:43:57 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:08:45 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder43
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:31
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 31).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 10).
+    self assert:(foundNode node charIndex = 31).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:44:31 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder44
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:32
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 32).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 10).
+    self assert:(foundNode node charIndex = 31).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:45:35 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder45
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:10
+                position:33
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 10).
+    self assert:((foundNode position) = 33).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:45:55 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder46
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 14:47:00 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder47
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'd').
+    self assert:(foundNode node line = 11).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:34:49 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder48
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:22
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 22).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'd').
+    self assert:(foundNode node line = 11).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:36:14 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder49
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:b:').
+    self assert:(foundNode node selectorsPosition size = 2).
+    self assert:((foundNode node selectorsPosition at:1) = 23).
+    self assert:((foundNode node selectorsPosition at:2) = 31).
+    self assert:(foundNode node lines size = 2).
+    self assert:((foundNode node lines at:1) = 11).
+    self assert:((foundNode node lines at:2) = 11).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:36:58 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:08:55 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder5
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:1
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode position) = 1).
+    self assert:((foundNode line) = 4).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:40:43 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder50
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:28
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 28).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:b:').
+    self assert:(foundNode node selectorsPosition size = 2).
+    self assert:((foundNode node selectorsPosition at:1) = 23).
+    self assert:((foundNode node selectorsPosition at:2) = 31).
+    self assert:(foundNode node lines size = 2).
+    self assert:((foundNode node lines at:1) = 11).
+    self assert:((foundNode node lines at:2) = 11).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:41:42 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:01 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder51
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:29
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 29).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node value = 3).
+    self assert:(foundNode node line = 11).
+    self assert:(foundNode node charIndex = 29).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:42:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder52
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:30
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 30).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node value = 3).
+    self assert:(foundNode node line = 11).
+    self assert:(foundNode node charIndex = 29).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:54:26 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder53
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:31
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 31).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node value = 3).
+    self assert:(foundNode node line = 11).
+    self assert:(foundNode node charIndex = 29).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:55:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder54
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:32
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 32).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:b:').
+    self assert:(foundNode node selectorsPosition size = 2).
+    self assert:((foundNode node selectorsPosition at:1) = 23).
+    self assert:((foundNode node selectorsPosition at:2) = 32).
+    self assert:(foundNode node lines size = 2).
+    self assert:((foundNode node lines at:1) = 11).
+    self assert:((foundNode node lines at:2) = 11).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:55:30 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:06 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder55
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:33
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 33).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:b:').
+    self assert:(foundNode node selectorsPosition size = 2).
+    self assert:((foundNode node selectorsPosition at:1) = 23).
+    self assert:((foundNode node selectorsPosition at:2) = 32).
+    self assert:(foundNode node lines size = 2).
+    self assert:((foundNode node lines at:1) = 11).
+    self assert:((foundNode node lines at:2) = 11).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:56:34 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:12 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder550
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:  3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:30
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 30).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:b:').
+    self assert:(foundNode node selectorsPosition size = 2).
+    self assert:((foundNode node selectorsPosition at:1) = 23).
+    self assert:((foundNode node selectorsPosition at:2) = 34).
+    self assert:(foundNode node lines size = 2).
+    self assert:((foundNode node lines at:1) = 11).
+    self assert:((foundNode node lines at:2) = 11).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 03-03-2011 / 21:01:09 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:17 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder551
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:  3  b:  u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:37
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 37).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'floor:b:').
+    self assert:(foundNode node selectorsPosition size = 2).
+    self assert:((foundNode node selectorsPosition at:1) = 23).
+    self assert:((foundNode node selectorsPosition at:2) = 34).
+    self assert:(foundNode node lines size = 2).
+    self assert:((foundNode node lines at:1) = 11).
+    self assert:((foundNode node lines at:2) = 11).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 03-03-2011 / 21:02:22 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:22 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder552
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:  3  b:  u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:38
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 38).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 03-03-2011 / 21:02:56 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder553
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:  3  b:  u  .
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:40
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 40).
+    self assert:(foundNode node isMessage).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 03-03-2011 / 21:04:05 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder56
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:34
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 34).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 11).
+    self assert:(foundNode node charIndex = 34).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:56:58 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder57
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:35
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 35).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'u').
+    self assert:(foundNode node line = 11).
+    self assert:(foundNode node charIndex = 34).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:57:56 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder58
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:11
+                position:36
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 11).
+    self assert:((foundNode position) = 36).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:58:09 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder59
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:58:52 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder6
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:20
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 5).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:41:15 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder60
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode node isSelf).
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 15:59:49 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder61
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 25).
+    self assert:(foundNode node isSelf).
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:04:08 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder62
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:26
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 26).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors isSymbol).
+    self assert:(foundNode node selectors asString = 'rememberSymbolUsed:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 26).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 12).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:04:35 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder63
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:44
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 44).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors isSymbol).
+    self assert:(foundNode node selectors asString = 'rememberSymbolUsed:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 26).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 12).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:06:15 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder64
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil. c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:45
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 45).
+    self assert:(foundNode node isConstant).
+    self assert:((foundNode node type) = #Nil).
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 45).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:06:43 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder65
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:48
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 48).
+    self assert:(foundNode node isConstant).
+    self assert:((foundNode node type) = #Nil).
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 45).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:08:29 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder66
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:49
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 49).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:09:03 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder67
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:50
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 50).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:29:10 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder68
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c call:b. b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:51
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 51).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:29:26 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder69
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c call:b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:52
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 52).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'c').
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 52).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:30:18 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder7
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 4).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:42:37 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder70
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c call:b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:53
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 53).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'c').
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 52).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:31:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder71
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call:b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:54
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 54).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'c').
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 52).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:32:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder72
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call:b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:55
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 55).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'call:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 55).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 12).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 16:32:49 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:28 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder73
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:59
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 59).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'call:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 55).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 12).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:28:35 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder74
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:60
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 60).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors asString = 'call:').
+    self assert:(foundNode node selectorsPosition size = 1).
+    self assert:((foundNode node selectorsPosition at:1) = 55).
+    self assert:(foundNode node lines size = 1).
+    self assert:((foundNode node lines at:1) = 12).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:29:57 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:09:38 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder75
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:61
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 61).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'b').
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 61).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:30:16 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder76
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:62
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 62).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'b').
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 61).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:31:03 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder77
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:64
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 64).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:31:44 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder78
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:65
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 65).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:34:50 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder79
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:66
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 66).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'b').
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 66).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:35:28 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder8
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:22
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 5).
+    self assert:((foundNode position) = 22).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node value = 3).
+    self assert:(foundNode node line = 5).
+    self assert:(foundNode node charIndex = 22).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:43:50 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder80
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:79
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 79).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'd').
+    self assert:(foundNode node line = 12).
+    self assert:(foundNode node charIndex = 78).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 17:36:26 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder81
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:12
+                position:80
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 12).
+    self assert:((foundNode position) = 80).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:36:59 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder82
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:13
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 13).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:38:37 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder83
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:13
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 13).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'array').
+    self assert:(foundNode node line = 13).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:39:51 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder84
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:13
+                position:26
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 13).
+    self assert:((foundNode position) = 26).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'array').
+    self assert:(foundNode node line = 13).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:40:54 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder85
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:13
+                position:30
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 13).
+    self assert:((foundNode position) = 30).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node type = #Array).
+    self assert:(foundNode node line = 13).
+    self assert:(foundNode node charIndex = 30).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:41:18 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder86
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:14
+                position:30
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 14).
+    self assert:((foundNode position) = 30).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node type = #Array).
+    self assert:(foundNode node line = 13).
+    self assert:(foundNode node charIndex = 30).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:42:54 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder87
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:15
+                position:22
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 15).
+    self assert:((foundNode position) = 22).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:43:20 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder88
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:44:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder89
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'val').
+    self assert:(foundNode node line = 16).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 17:51:48 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder9
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:nil. 
+                    array:=#(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:5
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 5).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode node value = 3).
+    self assert:(foundNode node line = 5).
+    self assert:(foundNode node charIndex = 22).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 25-02-2011 / 13:44:06 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder90
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:24
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 24).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'val').
+    self assert:(foundNode node line = 16).
+    self assert:(foundNode node charIndex = 21).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:16:29 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder91
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 25).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:16:46 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder92
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:27
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 27).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:17:24 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder93
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:28
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 28).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name isSymbol).
+    self assert:(foundNode node name asString = 'ConstantNode').
+    self assert:(foundNode node line = 16).
+    self assert:(foundNode node charIndex = 28).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:17:40 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder94
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:40
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 40).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name isSymbol).
+    self assert:(foundNode node name asString = 'ConstantNode').
+    self assert:(foundNode node line = 16).
+    self assert:(foundNode node charIndex = 28).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:19:16 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder95
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:17
+                position:41
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 17).
+    self assert:((foundNode position) = 41).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode node selectors isSymbol).
+    self assert:(foundNode node selectors asString = 'type:value:').
+    self assert:(foundNode node selectorsPosition size = 2).
+    self assert:((foundNode node selectorsPosition at:1) = 41).
+    self assert:((foundNode node selectorsPosition at:2) = 41).
+    self assert:(foundNode node lines size = 2).
+    self assert:((foundNode node lines at:1) = 16).
+    self assert:((foundNode node lines at:2) = 17).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:19:53 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder96
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:16
+                position:55
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 16).
+    self assert:((foundNode position) = 55).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'tokenType').
+    self assert:(foundNode node line = 16).
+    self assert:(foundNode node charIndex = 46).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:23:07 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder97
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:17
+                position:57
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 17).
+    self assert:((foundNode position) = 57).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'tokenValue').
+    self assert:(foundNode node line = 17).
+    self assert:(foundNode node charIndex = 47).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 28-02-2011 / 18:24:30 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder98
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:20
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 20).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:25:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinder99
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd tokenType array|
+                    u 
+                    := 
+                     3.
+                    b:=u.
+                    c:=u 
+                        floor 
+                        aa   .
+                    d  floor: u.
+                    d floor:3  b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4 
+                    5 6 
+                    ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:18
+                position:21
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 18).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 28-02-2011 / 18:26:31 / Jakub <zelenja7@fel.cvut.cz>"
+! !
+
+!FinderTests methodsFor:'FinderTestsErrorNode'!
+
+testFinderErrorNode1
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+                    
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:2
+                position:1
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 2).
+    self assert:((foundNode position) = 1).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 15:34:00 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode10
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 f
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:9
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 9).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:27:59 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode11
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor:
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:14
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 14).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:29:25 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode12
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: (
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:16
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 16).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:30:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode13
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( s
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:18
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 18).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:31:44 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode14
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:21
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 21).
+    self assert:(foundNode node isSelf).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:33:10 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode15
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:22
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 22).
+    self assert:(foundNode node isSelf).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:33:20 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode16
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:23
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 23).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:35:09 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode17
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:26
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 26).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:36:02 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode18
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:25
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 25).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 02-03-2011 / 17:38:35 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 03-03-2011 / 18:22:41 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode19
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:26
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 26).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 02-03-2011 / 20:01:58 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 03-03-2011 / 18:23:37 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode2
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|                    
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:2
+                position:2
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 2).
+    self assert:((foundNode position) = 2).
+    self assert:(foundNode statement isErrorNode).
+    self assert:(foundNode statement errorToken = ':=').
+    self assert:(foundNode beforeStatement isNil).
+
+    "Created: / 02-03-2011 / 15:34:12 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode20
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:)
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:27
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 27).
+    self assert:(foundNode node isErrorNode).
+    self assert:(foundNode statement isAssignment).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 03-03-2011 / 18:24:01 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode21
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:) r
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:28
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 28).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isMessage).
+
+    "Created: / 03-03-2011 / 18:26:16 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode22
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:) round:
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:34
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 34).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 03-03-2011 / 18:27:16 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode23
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:) round: a
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:36
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 36).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode statement isAssignment).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 03-03-2011 / 21:05:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode24
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:) round: a:
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:37
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 37).
+    self assert:(foundNode node isSelectorNode).
+    self assert:(foundNode statement isAssignment).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isSelectorNode).
+
+    "Created: / 03-03-2011 / 21:05:49 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode25
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:) round: a:. 
+:
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:2
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 4).
+    self assert:((foundNode position) = 2).
+    self assert:(foundNode node isErrorNode).
+    self assert:(foundNode statement isErrorNode).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 03-03-2011 / 21:09:10 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode26
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3 floor: ( self b b:) round: a:. 
+:=
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:4
+                position:3
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 4).
+    self assert:((foundNode position) = 3).
+    self assert:(foundNode node isErrorNode).
+    self assert:(foundNode statement isErrorNode).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isAssignment).
+
+    "Created: / 03-03-2011 / 21:12:12 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode3
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+||                    
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:2
+                position:3
+                tree:collector tree.
+    self assert:(foundNode beforeNode).
+    self assert:((foundNode line) = 2).
+    self assert:((foundNode position) = 3).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 16:31:36 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode4
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:2
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 2).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'b').
+    self assert:(foundNode node line = 3).
+    self assert:(foundNode node charIndex = 1).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 02-03-2011 / 16:33:15 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode5
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:3
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 3).
+    self assert:(foundNode node isVariable).
+    self assert:(foundNode node name = 'b').
+    self assert:(foundNode node line = 3).
+    self assert:(foundNode node charIndex = 1).
+    self assert:(foundNode statement isMessage).
+
+    "Created: / 02-03-2011 / 16:38:07 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode6
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b :
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:4
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 4).
+    self assert:(foundNode node isErrorNode).
+    self assert:(foundNode node errorToken = ':').
+    self assert:(foundNode node line = 3).
+    self assert:(foundNode node charIndex = 3).
+    self assert:(foundNode statement isErrorNode).
+    self assert:(foundNode beforeStatement notNil).
+    self assert:(foundNode beforeStatement isVariable).
+
+    "Created: / 02-03-2011 / 16:38:34 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode7
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b :=
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:5
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 5).
+    self assert:(foundNode node isAssignment).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 16:41:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode8
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:7
+                tree:collector tree.
+    self assert:(foundNode inNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 7).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:26:32 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testFinderErrorNode9
+    |collector finder foundNode|
+
+    collector := self 
+                doForSource:'
+|helperNode b c d|
+b := 3
+                    u := 3.
+                    b:=u.
+                    c:=u floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    finder := SmallSenseFinder new.
+    foundNode := finder 
+                find:3
+                position:8
+                tree:collector tree.
+    self assert:(foundNode afterNode).
+    self assert:((foundNode line) = 3).
+    self assert:((foundNode position) = 8).
+    self assert:(foundNode node isConstant).
+    self assert:(foundNode statement isAssignment).
+
+    "Created: / 02-03-2011 / 17:27:33 / Jakub <zelenja7@fel.cvut.cz>"
+! !
+
+!FinderTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__GenericEditSupport.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,67 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+EditSupport subclass:#GenericEditSupport
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Services'
+!
+
+!GenericEditSupport class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!GenericEditSupport methodsFor:'accessing'!
+
+language
+    ^nil
+
+    "Created: / 24-07-2013 / 23:44:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GenericEditSupport class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__GroovyCompletionEngineSimple.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,114 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+JavaCompletionEngineSimple subclass:#GroovyCompletionEngineSimple
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Groovy'
+!
+
+!GroovyCompletionEngineSimple class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!GroovyCompletionEngineSimple class methodsFor:'accessing-definitions'!
+
+patternDefinitionsForAnalysis
+    ^ super patternDefinitionsForAnalysis , {
+        #analyzeLocalDef1:              .  '[[:def:]] [[:Identifier:]] ( = | ; )' .
+    }
+
+    "
+    self flush; patternsForAnalysis
+    "
+
+    "Created: / 23-05-2014 / 10:24:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+patternDefinitionsForCompletion
+
+    ^super patternDefinitionsForCompletion , {
+        #completeLocalDef:              . '( ', PatternPrimitiveType , ' | ' , PatternReferenceType , ' | [[:def:]] ) [[:Identifier:]] [[:CARET:]]' .
+    }
+
+    "
+    self flush.
+    self patternsForCompletion
+    "
+
+    "Created: / 19-05-2014 / 12:32:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GroovyCompletionEngineSimple methodsFor:'accessing-class'!
+
+scannerClass
+    "raise an error: this method should be implemented (TODO)"
+
+    ^ GroovyScanner
+
+    "Created: / 13-05-2014 / 17:46:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GroovyCompletionEngineSimple methodsFor:'analysis'!
+
+analyzeLocalDef1: match
+    "Analyze:
+
+    def <identifier> ;
+
+    "
+    | name |
+
+    self assert: match size = 3.
+    name := (match at: match size - 1) value.
+    locals at: name put: nil.
+
+    "Created: / 23-05-2014 / 10:26:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GroovyCompletionEngineSimple class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__GroovyCompletionEngineSimpleTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,455 @@
+"{ Encoding: utf8 }"
+
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractJavaCompletionEngineTests subclass:#GroovyCompletionEngineSimpleTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!GroovyCompletionEngineSimpleTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!GroovyCompletionEngineSimpleTests methodsFor:'accessing-classes'!
+
+completionEngineClass
+    ^ GroovyCompletionEngineSimple
+
+    "Created: / 22-05-2014 / 16:39:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completionLanguage
+    ^ GroovyLanguage instance
+
+    "Created: / 07-03-2015 / 10:35:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GroovyCompletionEngineSimpleTests methodsFor:'tests - analysis'!
+
+test_analyze_01a
+
+    self complete:'import java.util.Array;┃'.
+
+    self assert: (engine instVarNamed: #imports) size == 1.
+    self assert: (engine instVarNamed: #imports) first = 'java.util.Array'
+
+    "Created: / 22-05-2014 / 17:08:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_01b
+
+    self complete:'import java.util.*;┃'.
+
+    self assert: (engine instVarNamed: #imports) size == 1.
+    self assert: (engine instVarNamed: #imports) first = 'java.util.*'
+
+    "Created: / 22-05-2014 / 17:08:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_01c
+
+    self complete:'import java.util.*;
+                   import java.lang.reflect.Field;┃'.
+
+    self assert: (engine instVarNamed: #imports) size == 2.
+    self assert: (engine instVarNamed: #imports) first = 'java.util.*'.
+    self assert: (engine instVarNamed: #imports) second = 'java.lang.reflect.Field'.
+
+    "Created: / 22-05-2014 / 17:09:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_boolean
+
+    self complete:'boolean  var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'boolean' .
+
+    "Created: / 23-05-2014 / 09:24:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_byte
+
+    self complete:'byte var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'byte' .
+
+    "Created: / 23-05-2014 / 09:23:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_char
+
+    self complete:'char  var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'char' .
+
+    "Created: / 23-05-2014 / 09:24:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_def
+
+    self complete:'def var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') isNil .
+
+    "Created: / 23-05-2014 / 09:26:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_double
+
+    self complete:'double  var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'double' .
+
+    "Created: / 23-05-2014 / 09:24:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_float
+
+    self complete:'float  var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'float' .
+
+    "Created: / 23-05-2014 / 09:24:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_int_1
+
+    self complete:'int var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'int' .
+
+    "Created: / 23-05-2014 / 09:19:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_int_2
+
+    self complete:'int var = 10; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'int' .
+
+    "Created: / 23-05-2014 / 09:22:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_long
+
+    self complete:'long var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'long' .
+
+    "Created: / 23-05-2014 / 09:23:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_ref_full
+
+    self complete:'java.util.ArrayList var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'java.util.ArrayList' .
+
+    "Created: / 23-05-2014 / 09:27:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_ref_short
+
+    self complete:'ArrayList var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'ArrayList' .
+
+    "Created: / 23-05-2014 / 09:26:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_02_short
+
+    self complete:'short var; ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 1.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var') .
+    self assert: ((engine instVarNamed: #locals) at: 'var') = 'short' .
+
+    "Created: / 23-05-2014 / 09:23:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_analyze_03a
+
+    self complete:' int var1; 
+                    def var2 = var1 + ┃'.
+
+    self assert: (engine instVarNamed: #locals) size == 2.
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var1') .
+    self assert: ((engine instVarNamed: #locals) at: 'var1') = 'int' .
+
+    self assert: ((engine instVarNamed: #locals) includesKey: 'var2') .
+    self assert: ((engine instVarNamed: #locals) at: 'var2') = nil .
+
+    "Created: / 23-05-2014 / 10:32:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GroovyCompletionEngineSimpleTests methodsFor:'tests - completion'!
+
+test_complete_01a
+
+    self complete:'import java.uti┃'.
+
+    self assert: result notEmpty.
+    self assert: (result allSatisfy:[:each | each class == JavaImportPO ]).
+    self assert: (result contains:[:each | each import = 'java.util.*' ]).
+    self assert: (result contains:[:each | each import = 'java.util.zip.*' ]).
+    self assert: (result contains:[:each | each import = 'java.util.ArrayList' ]).
+
+    "Created: / 22-05-2014 / 17:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_02a
+
+    self complete:'im┃'.
+
+    self assert: result notEmpty.
+    self assert: (result contains:[:each | each isSmallSenseSnippetPO and:[each value = 'import '] ]).
+
+    "Created: / 22-05-2014 / 17:33:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_03a
+    "
+    Test variable completion"
+
+    self complete:'int  ival = 10;
+                   List ilist = new ArrayList();
+                   il┃'.
+
+    self assert: result size >= 2.
+    self assert: (result contains:[:each | each isSmallSenseVariablePO and:[each name = 'ilist']]).
+    self assert: (result contains:[:each | each isSmallSenseVariablePO and:[each name = 'ival']]) .
+
+    "Created: / 23-05-2014 / 10:30:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_03b
+    "
+    Test variable completion"
+
+    self complete:'int  ival = 10;
+                   List ilist = new ArrayList();
+                   i┃'.
+
+    self assert: result size >= 2.
+    self assert: (result contains:[:each | each isSmallSenseVariablePO and:[each name = 'ilist'] ]).
+    self assert: (result contains:[:each | each isSmallSenseVariablePO and:[each name = 'ival'] ]).
+
+    "Created: / 23-05-2014 / 10:36:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_03c
+    "
+    Test variable completion"
+
+    self complete:'int  ival = 10;
+                   List ilist = new ArrayList();
+                   ilist.add( i┃ )'.
+
+    self assert: result size >= 2.
+    self assert: (result contains:[:each | each isSmallSenseVariablePO and:[each name = 'ilist'] ]).
+    self assert: (result contains:[:each | each isSmallSenseVariablePO and:[each name = 'ival'] ]).
+
+    "Created: / 23-05-2014 / 10:38:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_03d
+    "
+    Test pseudo-variable completion"
+
+    self complete:'th┃'.
+
+    self assert: result size >= 1.
+    self assert: (result contains:[:each | each isSmallSenseSnippetPO and:[each value = 'this '] ]).
+
+    "Created: / 23-05-2014 / 10:39:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_04a
+    "
+    Test class completion
+    "
+
+    | java_lang_ArrayList ctors pos |
+
+    self complete:'def list = new Arr┃'.
+
+    java_lang_ArrayList := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::util::ArrayList'  ]
+                            ifFalse:[ context environment classNamed: #'java/util/ArrayList'].
+    ctors := java_lang_ArrayList methodDictionary values select:[:e | e selector startsWith: '<init>' ].
+    pos := result select:[:each | each class == JavaConstructorPO and:[ each classes anElement == java_lang_ArrayList ] ].
+
+    self assert: result size >= ctors size.
+    ctors do:[:ctor |  
+        self assert: (pos contains:[:po | po selector == ctor selector ]).
+    ].
+
+    "Created: / 23-05-2014 / 11:12:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_04b
+    "
+    Test class completion
+    "
+
+    | java_lang_ArrayList ctors pos |
+
+    self complete:'def list = new java.util.Arr┃'.
+
+    java_lang_ArrayList := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::util::ArrayList'  ]
+                            ifFalse:[ context environment classNamed: #'java/util/ArrayList'].
+    ctors := java_lang_ArrayList methodDictionary values select:[:e | e selector startsWith: '<init>' ].
+    pos := result select:[:each | each class == JavaConstructorPO and:[ each classes anElement == java_lang_ArrayList ] ].
+
+    self assert: result size >= ctors size.
+    ctors do:[:ctor |  
+        self assert: (pos contains:[:po | po selector == ctor selector ]).
+    ].
+
+    "Created: / 23-05-2014 / 11:32:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_04c
+    "
+    Test class completion
+    "
+
+    | java_lang_ArrayList ctors pos |
+
+    self complete:'def list = new java.util.┃'.
+
+    java_lang_ArrayList := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::util::ArrayList'  ]
+                            ifFalse:[ context environment classNamed: #'java/util/ArrayList'].
+    ctors := java_lang_ArrayList methodDictionary values select:[:e | e selector startsWith: '<init>' ].
+    pos := result select:[:each | each class == JavaConstructorPO and:[ each classes anElement == java_lang_ArrayList ] ].
+
+    self assert: result size >= ctors size.
+    ctors do:[:ctor |  
+        self assert: (pos contains:[:po | po selector == ctor selector ]).
+    ].
+
+    "Created: / 23-05-2014 / 11:33:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_04d
+    "
+    Test class completion
+    "
+
+    | java_lang_ArrayList ctors pos |
+
+    self complete:'def list = new java.ut┃'.
+
+    java_lang_ArrayList := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::util::ArrayList'  ]
+                            ifFalse:[ context environment classNamed: #'java/util/ArrayList'].
+    ctors := java_lang_ArrayList methodDictionary values select:[:e | e selector startsWith: '<init>' ].
+    pos := result select:[:each | each class == JavaConstructorPO and:[ each classes anElement == java_lang_ArrayList ] ].
+
+    self assert: result size >= ctors size.
+    ctors do:[:ctor |  
+        self assert: (pos contains:[:po | po selector == ctor selector ]).
+    ].
+
+    "Created: / 23-05-2014 / 11:41:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_05a
+    "
+    Test method completion
+    "
+
+    | java_lang_ArrayList methods pos |
+
+    self complete:'def list = new java.util.ArrayList();
+                   list.addA┃'.
+
+    java_lang_ArrayList := context environment == Smalltalk 
+                            ifTrue:[ context environment classNamed: #'JAVA::java::util::ArrayList'  ]
+                            ifFalse:[ context environment classNamed: #'java/util/ArrayList'].
+
+    methods := java_lang_ArrayList methodDictionary values select:[:e | e selector startsWith: 'addA' ].
+    pos := result select:[:each | each isSmallSenseMethodPO and:[ each selector startsWith: 'addA' ] ].
+
+    self assert: result size >= methods size.
+    methods do:[:method |  
+        self assert: (pos contains:[:po | po selector == method selector ]).
+    ].
+
+    "Created: / 23-05-2014 / 11:43:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GroovyCompletionEngineSimpleTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__GroovyEditSupport.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,85 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+JavaEditSupport subclass:#GroovyEditSupport
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Groovy'
+!
+
+!GroovyEditSupport class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!GroovyEditSupport methodsFor:'accessing'!
+
+language
+    "superclass SmallSenseEditSupport says that I am responsible to implement this method"
+
+    | groovyLanguageClass |
+
+    groovyLanguageClass := Smalltalk at:#GroovyLanguage.
+    ^ groovyLanguageClass notNil ifTrue:[ groovyLanguageClass instance ] ifFalse: [ nil ].
+
+    "Created: / 04-10-2013 / 07:49:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GroovyEditSupport methodsFor:'accessing-classes'!
+
+completionEngineClass
+    "Returns a code completion engine class or nil, of 
+     no completion is supported"
+
+    ^ SmallSense::GroovyCompletionEngineSimple
+
+    "Created: / 04-10-2013 / 07:46:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+scannerClass
+    "Returns a class to use for scanning lines. If nil, scanning is
+     not supported and scanLine* methods will return an empty array."
+
+    ^ (Smalltalk at: #GroovyScanner)
+
+    "Created: / 22-10-2013 / 00:38:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ImplementorSearchProcessor.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,146 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSearchProcessor subclass:#ImplementorSearchProcessor
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!ImplementorSearchProcessor class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ImplementorSearchProcessor methodsFor:'accessing'!
+
+canDoNextStepFor: aPO
+    "Return true if navigation can take a next step for given PO
+     (i.e., if user can 'dive in'), false otherwise.
+     To be overriden by subclasses to avoid excessive processor creation."
+
+    self assert: aPO class == MethodPO.
+    ^ aPO classes size > 1
+
+    "Created: / 23-01-2015 / 22:17:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+processorForNextStepFor: aPO
+    "Return a processor for next navigation step for given PO.
+     If nil is returned, then there's no next step (i.e.,
+     a user connot 'dive in')"
+
+    | selector |
+
+    self assert: aPO class == MethodPO.
+    aPO classes size == 1 ifTrue:[ ^ nil ].
+    selector := aPO selector.
+    ^ PluggableSearchProcessor 
+            search:
+                [ :pattern :filter :env :level | 
+
+                    ((aPO classes 
+                        select:[:cls | pattern isNil or:[ pattern match: cls nameWithoutNameSpacePrefix relax: level ] ])  
+                        asArray sort:[ :a :b | a nameWithoutNameSpacePrefix < b nameWithoutNameSpacePrefix ])
+                        collect:[ :cls | cls compiledMethodAt: selector ]
+
+                ]
+            presentation:             
+                [ :method | 
+                    PluggablePO new
+                        label: (method mclass nameWithoutNameSpacePrefix) , ((' >> ', selector) asText colorizeAllWith: Color gray darker);
+                        subject: method.                        
+                ].
+
+    "Created: / 23-01-2015 / 22:06:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-01-2015 / 00:44:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ImplementorSearchProcessor methodsFor:'accessing - presentation'!
+
+label
+    "Return a label for this processor. This one is used as section label
+     in Spotter"
+
+    ^ 'Implementors'
+
+    "Created: / 10-01-2015 / 06:41:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ImplementorSearchProcessor methodsFor:'searching'!
+
+matchingObjectPOsFor: objects
+    | pos |
+
+    pos := OrderedCollection new: objects size.
+    objects keysAndValuesDo: [ :selector :classes |
+        pos add: (PO forClasses: classes selector: selector )
+
+    ].
+    ^ pos sort:[ :a :b | a label == b label ifTrue:[ a classes anElement name < b classes anElement name] ifFalse:[ a label < b label ] ]
+
+    "Created: / 30-04-2014 / 09:50:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-12-2014 / 23:50:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsForPattern:pattern filter: filter inEnvironment:environment relax: level 
+    | matching |
+
+    matching := Dictionary new.
+    pattern notNil ifTrue:[
+        environment 
+            allMethodsDo:[:mthd |
+                | selector name |
+
+                name := selector := mthd selector.
+                mthd isJavaMethod ifTrue:[ name := name upTo: $( ].
+                ((filter isNil or:[filter value: mthd]) and:[(pattern match:name relax: level)]) ifTrue:[
+                    (matching at: selector ifAbsentPut: [ Set new ]) add: mthd mclass
+                ].
+            ].
+    ].
+
+    ^ matching
+
+    "Created: / 12-12-2014 / 21:24:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-12-2014 / 23:51:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__Info.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,77 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#Info
+	instanceVariableNames:'manager errorneous'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types-Info'
+!
+
+!Info class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!Info methodsFor:'accessing'!
+
+errorneous:something
+    errorneous := something.
+! !
+
+!Info methodsFor:'testing'!
+
+isErrorneous
+    ^ errorneous == true
+
+    "Created: / 21-11-2014 / 16:37:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Info class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaCompletionEngine.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,222 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractJavaCompletionEngine subclass:#JavaCompletionEngine
+	instanceVariableNames:'completionNode completionScope'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java'
+!
+
+!JavaCompletionEngine class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaCompletionEngine methodsFor:'completion-individual'!
+
+addFieldsForTypeBinding:binding
+    | current |
+
+    current := binding.        
+    [ current notNil ] whileTrue:[  
+        current fields do:[:fbinding | 
+            result add: (PO forFieldBinding: fbinding )
+        ].  
+        current := current superclass.
+    ].
+
+    "Created: / 13-08-2014 / 21:39:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-08-2014 / 09:06:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsForReceiver: maybeReceiverToken startingWith: prefix    
+    ^ self addMethodsStartingWith: prefix
+
+    "Created: / 03-10-2013 / 17:46:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsForTypeBinding: binding
+    | current seen |
+
+    current := binding.        
+    seen := Set new.
+    [ current notNil ] whileTrue:[  
+        current methods do:[:mbinding |
+            mbinding isConstructor ifFalse:[
+                | selector |
+
+                selector := mbinding selector , mbinding signature.
+                (seen includes: selector) ifFalse:[
+                    result add: (PO forMethodBinding: mbinding).
+                    seen add: selector.
+                ].
+            ].
+        ].  
+        current := current superclass.
+    ].
+
+    "Created: / 13-08-2014 / 21:39:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-08-2014 / 22:54:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addVariablesInScope: scope
+    ((scope kind == JAVA org eclipse jdt internal compiler lookup Scope METHOD_SCOPE) or:[
+    scope kind == JAVA org eclipse jdt internal compiler lookup Scope BLOCK_SCOPE]) ifTrue:[ 
+        1 to: scope localIndex do:[:i | 
+            result add: (PO forLocalVariableBinding: (scope locals at:i) ) 
+        ].
+        self addVariablesInScope: (scope instVarNamed: #parent). "/ !!?!! Why 'scope parent' does not work?
+    ].
+
+    scope kind == JAVA org eclipse jdt internal compiler lookup Scope CLASS_SCOPE ifTrue:[ 
+        | type |
+
+        type := scope referenceType.
+        type notNil ifTrue:[ 
+            self addFieldsForTypeBinding: type binding.  
+        ].
+    ].
+
+    "Created: / 12-08-2014 / 10:41:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-08-2014 / 09:08:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaCompletionEngine methodsFor:'completion-nodes'!
+
+completeOnFieldType: node
+    node type acceptCompletionEngine: self
+
+    "Created: / 13-08-2014 / 21:04:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeOnQualifiedNameReference: node
+    | binding |
+
+    binding := node binding.
+    (binding notNil and:[binding problemId ~~ JAVA org eclipse jdt internal compiler lookup ProblemReasons NoError]) ifTrue:[
+        binding := binding type.
+        binding notNil ifTrue:[ 
+            self addMethodsForTypeBinding: binding.
+            self addFieldsForTypeBinding: binding.  
+        ].
+    ].
+
+    "Created: / 13-08-2014 / 21:32:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-08-2014 / 11:13:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeOnSingleNameReference: node
+    self addVariablesInScope: completionScope.
+    self addClassesStartingWith: node token.
+
+    "Created: / 13-08-2014 / 21:05:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeOnSingleTypeReference: node
+    self addClassesStartingWith: node token
+
+    "Created: / 13-08-2014 / 21:05:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaCompletionEngine methodsFor:'completion-private'!
+
+complete
+    
+    | position source rslt problemReporter parser tree searcher resolver  |
+
+    position := textView characterPositionOfCursor.
+
+    source := JAVA stx libjava tools Source new.
+    source setContents: textView list asStringWithoutEmphasis.
+    rslt := JAVA org eclipse jdt internal compiler CompilationResult
+                new: source _: 1 _: 1 _: 1000.  
+    problemReporter := JAVA org eclipse jdt internal compiler problem ProblemReporter
+                new: JAVA org eclipse jdt internal compiler DefaultErrorHandlingPolicies proceedWithAllProblems
+                  _: JAVA stx libjava tools parser Parser defaultCompilerOptions   
+                  _: JAVA stx libjava tools parser Parser defaultProblemFactory.
+
+    parser := JAVA org eclipse jdt internal codeassist complete CompletionParser 
+                new: problemReporter _: true.
+    [
+        tree := parser dietParse: source _: rslt _: position - 1"Java is 0-based" - 1"cursor is actualy one fter the end of token".
+    ] on: JAVA org eclipse jdt internal codeassist complete InvalidCursorLocation do:[:icl |
+        ^ result
+    ].
+    searcher := JAVA org eclipse jdt core dom NodeSearcher new: position - 1"Java is 0-based" - 1"cursor is actualy one fter the end of token".
+    tree traverse: searcher _: tree scope.
+    (searcher found notNil and:[searcher found isKindOf: JAVA org eclipse jdt internal compiler ast AbstractMethodDeclaration]) ifTrue:[ 
+        parser parseBlockStatements: searcher found _: tree.
+    ].
+
+
+    "
+    (SmallSense::ParseTreeInspector new node:tree source: codeView list asString) open
+    "
+
+    resolver := (Java classForName: 'stx.libjava.tools.environment.Resolver') new: problemReporter.
+    [ 
+        resolver resolve: tree.
+    ] on: JAVA org eclipse jdt internal codeassist complete CompletionNodeFound do:[:ex |  
+        completionNode := ex astNode.
+        completionScope := ex scope.
+    ].
+
+    context node: completionNode position: position.
+
+    (completionNode isNil or:[completionScope isNil]) ifTrue:[
+        result := JavaCompletionEngineSimple new complete: context.
+    ] ifFalse:[
+        completionNode acceptCompletionEngine: self.
+    ].
+
+    ^ result
+
+    "Created: / 02-10-2013 / 13:55:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 27-03-2015 / 18:09:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaCompletionEngine class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaCompletionEngineEnvironmentResource.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,80 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+TestResource subclass:#JavaCompletionEngineEnvironmentResource
+	instanceVariableNames:'booted'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!JavaCompletionEngineEnvironmentResource class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaCompletionEngineEnvironmentResource methodsFor:'running'!
+
+setUp
+    JavaVM isNil ifTrue:[ 
+        self signalInitializationError.
+    ].
+    
+    booted := JavaVM booted.
+
+    JavaVM booted ifFalse:[ 
+        [
+            JavaVM boot.                            
+        ] on: Error do:[:ex | 
+            self signalInitializationError.
+        ].
+    ].
+
+    "Created: / 22-05-2014 / 17:21:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+tearDown
+    booted ifFalse:[ 
+        Java flushAllJavaResources
+    ].
+
+    "Created: / 22-05-2014 / 17:21:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaCompletionEngineSimple.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,69 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractJavaCompletionEngineSimple subclass:#JavaCompletionEngineSimple
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java'
+!
+
+!JavaCompletionEngineSimple class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaCompletionEngineSimple methodsFor:'accessing-class'!
+
+scannerClass
+    "raise an error: this method should be implemented (TODO)"
+
+    ^ JavaScanner
+
+    "Created: / 13-05-2014 / 17:46:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaCompletionEngineSimple class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaCompletionEngineTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,146 @@
+"{ Encoding: utf8 }"
+
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractJavaCompletionEngineTests subclass:#JavaCompletionEngineTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!JavaCompletionEngineTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaCompletionEngineTests methodsFor:'accessing-classes'!
+
+completionEngineClass
+    "superclass SmallSense::CompletionEngineTests says that I am responsible to implement this method"
+
+    ^ JavaCompletionEngine
+
+    "Created: / 07-08-2014 / 02:00:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completionLanguage
+    ^ JavaLanguage instance
+
+    "Created: / 07-03-2015 / 10:35:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaCompletionEngineTests methodsFor:'tests'!
+
+test_method_01
+
+    <skip>
+
+    self complete:'public class Foo {
+        public int bar(Object o) {
+            return o.has┃
+        }
+    }'.
+
+    self assert: result notEmpty.
+    self assert: (result contains:[:each | each isSmallSenseMethodBindingPO
+                                                and:[ each binding selector = 'hashCode' ] ])
+
+    "Created: / 13-08-2014 / 02:05:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-08-2014 / 22:45:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_types_01
+
+    <skip>
+
+    self complete:'public class Foo {
+        public int addTo(Arra┃
+        }
+    }'.
+
+    self assert: result notEmpty.
+    self assert: (result contains:[:each | each isSmallSenseClassPO 
+                                                and:[ each klass == JAVA java util ArrayList ] ])
+
+    "Created: / 13-08-2014 / 00:35:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-08-2014 / 02:02:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_types_02
+
+    <skip>
+
+    self complete:'public class Foo {
+        protected Arra┃
+    }'.
+
+    self assert: result notEmpty.
+    self assert: (result contains:[:each | each isSmallSenseClassPO 
+                                                and:[ each klass == JAVA java util ArrayList ] ])
+
+    "Created: / 13-08-2014 / 00:40:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-08-2014 / 02:02:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_variables_01
+
+    <skip>
+
+    self complete:'public class Foo {
+        public int field;
+        public int sum(int number1, int number2) {
+            return num┃
+        }
+    }'.
+
+    self assert: result size == 3.
+    self assert: (result contains:[:each | each isSmallSenseVariableBindingPO
+                                                and:[ each binding name = 'number1' ] ]).
+    self assert: (result contains:[:each | each isSmallSenseVariableBindingPO
+                                                and:[ each binding name = 'number2' ] ]).
+    self assert: (result contains:[:each | each isSmallSenseVariableBindingPO
+                                                and:[ each binding name = 'field' ] ]).
+
+    "Created: / 07-08-2014 / 02:00:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-08-2014 / 09:08:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaConstructorPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,111 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+MethodPO subclass:#JavaConstructorPO
+	instanceVariableNames:'showPrefix'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java-Interface-PO'
+!
+
+!JavaConstructorPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaConstructorPO methodsFor:'accessing'!
+
+hint
+    ^ (classes collect:[:each | each javaPackage ]) asArray asStringWith:' , '.
+
+    "Created: / 24-06-2014 / 11:04:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    label isNil ifTrue:[
+	label := (classes anElement compiledMethodAt: selector) printStringForBrowserWithSelector: selector.
+	showPrefix ifTrue:[
+	    label := classes anElement javaPackage , '.' , label
+	].
+    ].
+    ^ label
+
+    "Created: / 15-05-2014 / 12:04:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showPrefix: aBoolean
+    showPrefix := aBoolean
+
+    "Created: / 15-05-2014 / 12:01:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringAlreadyWritten
+    "Answers a string already written in the textview"
+
+    ^ showPrefix ifTrue:[
+	context wordBeforeCursorConsisitingOfCharactersMatching:[:c | c isAlphaNumeric or:['$_.' includes: c] ]
+    ] ifFalse:[
+	super stringAlreadyWritten
+    ].
+
+    "Created: / 15-05-2014 / 12:06:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage: aProgrammingLanguage
+    "Answers a string to complete"
+
+    | string |
+
+    string := super stringToCompleteForLanguage: aProgrammingLanguage.
+    showPrefix ifTrue:[
+	string := classes anElement javaPackage , '.' , string
+    ].
+    ^ string
+
+    "Created: / 15-05-2014 / 12:07:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaConstructorPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaEditSupport.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,356 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+EditSupport subclass:#JavaEditSupport
+	instanceVariableNames:'lastTypedKey0 lastTypedKey1 lastTypedKey2 lastTypedKey3'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java'
+!
+
+!JavaEditSupport class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaEditSupport methodsFor:'accessing'!
+
+language
+    "superclass SmallSenseEditSupport says that I am responsible to implement this method"
+
+    | javaLanguageClass |
+
+    javaLanguageClass := Smalltalk at:#JavaLanguage.
+    ^ javaLanguageClass notNil ifTrue:[ javaLanguageClass instance ] ifFalse: [ nil ].
+
+    "Modified: / 04-10-2013 / 08:42:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaEditSupport methodsFor:'accessing-classes'!
+
+completionEngineClass
+    "Returns a code completion engine class or nil, of 
+     no completion is supported"
+
+    OperatingSystem getLoginName = 'jv' ifTrue:[
+        ^ SmallSense::JavaCompletionEngine
+    ].
+    ^ SmallSense::JavaCompletionEngineSimple
+
+    "Created: / 03-10-2013 / 17:45:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-08-2014 / 10:53:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+scannerClass
+    "Returns a class to use for scanning lines. If nil, scanning is
+     not supported and scanLine* methods will return an empty array."
+
+    ^ (Smalltalk at: #JavaScanner)
+
+    "Created: / 22-10-2013 / 00:38:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaEditSupport methodsFor:'editing'!
+
+electricInsertSnippet
+    | tokens  lastToken0 |
+
+    tokens := self scanLineAtCursor.
+    tokens isEmptyOrNil ifTrue:[
+        ^ false
+    ].
+    lastToken0 := tokens at:(tokens size - 3).
+    lastToken0 = 'Error' ifTrue:[
+        ^ false
+    ].
+    (tokens last > textView cursorCol) ifTrue:[
+        ^ false
+    ].
+    
+    "/ Insert try { ... }
+    
+    lastToken0 == #try ifTrue:[
+        (tokens size == 4 
+            or:[ (tokens size > 4) and:[ (tokens at:tokens size - 7) ~~ $. ] ]) 
+                ifTrue:[
+                    self electricInsertBlockOpenedBy:' {' closedBy:'}'.
+                    ^ true.
+                ]
+    ].
+    
+    "/ Insert catch (  ) { ... }
+    
+    lastToken0 == #catch ifTrue:[
+        (tokens size > 4 and:[ (tokens at:tokens size - 7) == $} ]) ifTrue:[
+            | cursorLine  cursorCol |
+
+            cursorLine := textView cursorLine.
+            cursorCol := textView cursorCol.
+            self electricInsertBlockOpenedBy:' (  ) {' closedBy:'}'.
+            textView cursorLine:cursorLine col:cursorCol + 3.
+            ^ true.
+        ].
+    ].
+    
+    "/ Insert finally { ... }
+    
+    lastToken0 == #finally ifTrue:[
+        (tokens size > 4 and:[ (tokens at:tokens size - 7) == $} ]) ifTrue:[
+            self electricInsertBlockOpenedBy:' {' closedBy:'}'.
+            ^ true.
+        ].
+    ].
+    
+    "/ Insert if/while/synchronized ( )  { ... }
+    
+    (#( #if #while #synchronized ) includes:lastToken0) ifTrue:[
+        (tokens size = 4) ifTrue:[
+            | cursorLine  cursorCol |
+
+            cursorLine := textView cursorLine.
+            cursorCol := textView cursorCol.
+            self electricInsertBlockOpenedBy:' (  ) {' closedBy:'}'.
+            textView cursorLine:cursorLine col:cursorCol + 3.
+            ^ true.
+        ].
+    ].
+    
+    "/ Insert for ( ; ; )  { ... }
+    
+    (lastToken0 == #for) ifTrue:[
+        (tokens size = 4) ifTrue:[
+            | cursorLine  cursorCol |
+
+            cursorLine := textView cursorLine.
+            cursorCol := textView cursorCol.
+            self electricInsertBlockOpenedBy:' ( ; ; ) {' closedBy:'}'.
+            textView cursorLine:cursorLine col:cursorCol + 3.
+            ^ true.
+        ].
+    ].
+    ^ false
+
+    "Created: / 22-10-2013 / 01:53:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:00:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaEditSupport methodsFor:'event handling'!
+
+keyPress: key x:x y:y in: view
+
+    "Handles an event in given view (a subview of codeView).
+     If the method returns true, the event will not be processed
+     by the view."
+
+    view ~~ textView ifTrue:[ ^ false ].
+
+    (self keyPressIgnored: key) ifTrue:[
+        ^ true.
+    ]. 
+
+    lastTypedKey3 := lastTypedKey2.
+    lastTypedKey2 := lastTypedKey1.
+    lastTypedKey1 := lastTypedKey0.
+    lastTypedKey0 := key.
+
+    key == #CodeCompletion ifTrue:[ 
+        | controller |
+
+        (controller := self textView completionSupport) notNil ifTrue:[
+            ^ controller handleKeyPress:key x:x y:y 
+        ].
+        ^ false
+    ]. 
+
+    key == #Return ifTrue:[ 
+        ^ self keyPressReturn.
+    ]. 
+
+    UserPreferences current smallSenseElectricEditSupportEnabled ifFalse:[ ^ false ].     
+
+    key == ${ ifTrue:[
+        ^ self keyPressOpenCurly
+    ].
+
+    key == Character space ifTrue:[
+        ^ self electricInsertSnippet
+    ].
+
+    ^ false
+
+    "Created: / 07-03-2010 / 09:36:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-05-2015 / 00:09:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressOpenCurly
+    | line tokens i |
+
+    line := textView listAt: textView cursorLine.
+    line notEmptyOrNil ifTrue:[
+        i := line size.
+        [ i > 0 and:[(line at: i) isSeparator] ] whileTrue:[ i := i - 1 ].
+        (i ~~ 0 and:[textView cursorCol < i]) ifTrue:[
+            ^ false.        ].
+    ] ifFalse:[
+        self electricInsertBlockOpenedBy:'{' closedBy:'}'. 
+        ^ true
+    ].
+
+    tokens := self scanLineAtCursor.
+    tokens notEmptyOrNil ifTrue:[
+        | column |
+
+        column := textView cursorCol.
+        (tokens at: tokens size - 3) = 'Error' ifTrue:[ ^ false ].
+        1 to: tokens size - 3 by: 4 do:[:i |
+            (column between: (tokens at: i + 2) and: (tokens at: i + 3)) ifTrue:[
+                (tokens at: i) == #String ifTrue:[ ^ false ].
+
+                self electricInsertBlockOpenedBy:'{' closedBy:'}'. 
+                ^ true.
+            ].
+        ].
+    ].
+
+    self electricInsertBlockOpenedBy:'{' closedBy:'}'. 
+    ^ true
+
+    "Created: / 04-08-2013 / 01:54:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:01:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressReturn
+    | line c i indent lineNr ccontroler  |
+
+    textView isInInsertMode ifFalse:[ ^ false ].
+    ccontroler := textView completionSupport.
+    (ccontroler notNil and:[ ccontroler isCompletionViewShown ]) ifTrue:[ 
+        ^ false.
+    ].
+
+    "/ First, check if the cursor is at the end of line, i.e., if
+    "/ there's no text after the cursor...
+    lineNr := textView cursorLine.
+    line := textView listAt: lineNr.
+    i := line size.
+    i >= textView cursorCol ifTrue:[ 
+        [ i > 0 and:[ (c := line at:i) isSeparator ] ] whileTrue:[ i := i - 1 ].    
+        i <= textView cursorCol ifFalse:[ 
+            "/ If not, do not indent...
+            ^ false 
+        ].
+    ].
+
+    "/ Search for closest non-empty line above
+    lineNr := textView cursorLine.
+    [ lineNr > 0 and:[ (line := textView list at: lineNr ifAbsent:[nil]) isEmptyOrNil ] ] whileTrue:[ lineNr := lineNr - 1 ].
+    lineNr == 0 ifTrue:[ 
+        "/ No such line found, givin up
+        ^ false.
+    ].
+    indent := line indexOfNonSeparator.
+    "/ Look for opening curly, if found, increase indent...
+    i := line size.
+    [ i > 0 and:[ (c := line at:i) isSeparator ] ] whileTrue:[ i := i - 1 ].
+    (i > 0 and:[ c == ${ ]) ifTrue:[ 
+        indent := indent + 4.
+    ].
+    textView undoableDo:[
+        textView insertCharAtCursor:(Character cr).
+        textView cursorCol: indent.
+    ].
+    ^ true
+
+    "Created: / 13-08-2014 / 15:30:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-05-2015 / 00:17:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaEditSupport methodsFor:'initialization'!
+
+initializeForService: anEditService    
+    super initializeForService: anEditService.
+    textView autoIndent:true.
+
+    "Created: / 27-09-2013 / 13:55:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 12-02-2015 / 00:01:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaEditSupport methodsFor:'private'!
+
+tokenAtCursorLine
+    | scanner token |
+
+    scanner := (Smalltalk at:#JavaScanner) for: (textView listAt: textView cursorLine) string.
+
+    [ 
+        [ 
+            token := scanner nextToken.
+            (token ~~ #EOF and:[ scanner tokenEndPosition + 1 < textView cursorCol ])
+        ] whileTrue.
+    ] on: Error do:[
+        token := nil.
+    ].
+    ^ token
+
+    "Created: / 04-08-2013 / 02:00:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:02:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+tokensAtCursorLine
+    | scanner token |
+
+    scanner := (Smalltalk at:#JavaScanner) for: (textView listAt: textView cursorLine) string.
+    ^ OrderedCollection streamContents:[:tokens |
+        [ token := scanner nextToken.token ~~ #EOF ] whileTrue:[
+            tokens nextPut: token.
+        ].
+    ].
+
+    "Created: / 04-08-2013 / 01:57:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:02:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaEditSupport class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaEditSupportTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,153 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+EditSupportTests subclass:#JavaEditSupportTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!JavaEditSupportTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaEditSupportTests methodsFor:'accessing-classes'!
+
+editSupportClass
+    "superclass SmallSense::EditSupportTests says that I am responsible to implement this method"
+
+    ^ JavaEditSupport
+
+    "Created: / 13-08-2014 / 15:16:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaEditSupportTests methodsFor:'tests - return'!
+
+test_return_01a
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.
+    codeView contents:'
+public class SimpleClient {
+}'.
+
+    codeView setCursorLine: 2 col: 28.
+
+    codeViewInteractor type: #Return.
+
+    self assert: (codeView cursorCol = 5).  
+    self assert: (codeView cursorLine = 3).
+    self assert: (codeView list at: 3) isEmptyOrNil.
+
+    "Created: / 13-08-2014 / 15:34:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_return_01b
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.
+    codeView contents:'
+public class SimpleClient {
+}'.
+
+    codeView setCursorLine: 2 col: 35.
+
+    codeViewInteractor type: #Return.
+
+    self assert: (codeView cursorCol = 5).  
+    self assert: (codeView cursorLine = 3).
+
+    "Created: / 13-08-2014 / 15:34:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_return_02a
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.
+    codeView contents:'
+public class SimpleClient {
+    int i;
+}'.
+
+    codeView setCursorLine: 3 col: 11.
+
+    codeViewInteractor type: #Return.
+
+    self assert: (codeView cursorCol = 5).  
+    self assert: (codeView cursorLine = 4).
+
+    "Created: / 13-08-2014 / 15:33:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_return_02b
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.
+    codeView contents:'
+public class SimpleClient {
+    int i;
+
+
+}'.
+
+    codeView setCursorLine: 4 col: 15.
+
+    codeViewInteractor type: #Return.
+
+    self assert: (codeView cursorCol = 5).  
+    self assert: (codeView cursorLine = 5).
+
+    "Created: / 13-08-2014 / 15:33:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_return_03b
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.
+    codeView contents:'
+public class SimpleClient {
+    int i;
+
+
+}'.
+
+    codeView setCursorLine: 3 col: 9.
+
+    codeViewInteractor type: #Return.
+
+    self assert: (codeView cursorCol = 1).  
+    self assert: (codeView cursorLine = 4).
+    self assert: (codeView list at: 4) = 'i;'
+
+    "Created: / 13-08-2014 / 20:39:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__JavaImportPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,142 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#JavaImportPO
+	instanceVariableNames:'klass import icon'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java-Interface-PO'
+!
+
+!JavaImportPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!JavaImportPO class methodsFor:'image specs'!
+
+packageIcon
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self icon inspect
+     ImageEditor openOnClass:self andSelector:#icon
+     Icon flushCachedIcons
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:'Expecco::JIClassTree::PackagePO icon'
+        ifAbsentPut:[(Depth8Image new) width: 16; height: 16; photometric:(#palette); bitsPerSample:(#[8]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'
+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@AT@@@@@@@@@@@@@@0XFA XOA XFA L@@@@@@@$E@ HME TB@ 4I@@@@@@@H@ @AB!!XB
+@@DJB@@@@@@@C@HA@P\V@ DAA00@@@@@@@,MB \TE04JA1PK@@@@@ATOE!!XVE1\WE!!XVC1T@@@@@D@TB@ 4WAPHBCQ@@@@@@@@8B@@DJE H@@P(N@@@@@@@Q
+@ DAA1XB@PDGDP@@@@@@D04JA1PVCP(GEAL@@@@@@@PRD!!HRC1HRD!!HD@@@@@@@@@@@@@AT@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@a') ; colorMapFromArray:#[249 241 187 237 209 166 229 201 161 191 130 49 197 131 50 219 191 158 193 122 45 215 185 152 191 117 42 193 119 43 215 184 151 183 109 40 187 113 42 206 171 139 169 96 35 147 85 31 174 99 37 165 92 34 160 89 33 162 89 34 199 160 130 113 60 23 158 112 88 121 79 64]; mask:((Depth1Image new) width: 16; height: 16; photometric:(#blackIs0); bitsPerSample:(#[1]); samplesPerPixel:(1); bits:(ByteArray fromPackedString:'@@@@@@B@G?0_?A?<G?0_?C?>G?0_?A?<G?0_?@B@@@@b') ; yourself); yourself]
+
+    "Created: / 20-10-2013 / 00:34:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaImportPO methodsFor:'accessing'!
+
+icon
+
+    icon isNil ifTrue:[
+        icon := klass notNil 
+                    ifTrue:[SystemBrowser iconForClass: klass]
+                    ifFalse:[self class packageIcon].
+    ].
+    ^icon
+
+    "Created: / 20-10-2013 / 00:32:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+import
+    ^ import
+!
+
+import:aString
+    import := aString.
+
+    "Modified: / 20-05-2014 / 11:43:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+klass
+    ^ klass
+!
+
+klass:something
+    klass := something.
+!
+
+label
+    ^ import
+
+    "Created: / 20-05-2014 / 11:31:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringAlreadyWritten
+    "Answers a string already written in the textview"    
+
+    ^ context wordBeforeCursorConsisitingOfCharactersMatching:
+        [:c | c isAlphaNumeric or:['$_.' includes: c] ]
+
+    "Created: / 20-10-2013 / 00:19:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage: aProgrammingLanguage
+    "Answers a string to complete"
+
+    ^ import , ';'.
+
+    "Created: / 20-10-2013 / 00:39:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 10:10:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!JavaImportPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__Manager.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,340 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#Manager
+	instanceVariableNames:'classes accessLock updater updaterThread seqno'
+	classVariableNames:'Instance'
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types-Info'
+!
+
+!Manager class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!Manager class methodsFor:'instance creation'!
+
+flush
+    "flushes the cached singleton"
+
+    self flushSingleton
+
+    "
+     self flushSingleton
+    "
+
+    "Created: / 16-12-2011 / 01:37:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-11-2014 / 17:34:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+flushSingleton
+    "flushes the cached singleton"
+
+    Instance notNil ifTrue:[ 
+        Instance release.
+    ].
+    Instance := nil
+
+    "
+     self flushSingleton
+    "
+
+    "Modified: / 21-11-2014 / 17:34:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+instance
+    "returns a singleton"
+
+    Instance isNil ifTrue:[
+        Instance := self basicNew initialize.
+    ].
+    ^ Instance.
+
+    "Created: / 27-11-2011 / 15:30:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+new
+    "returns a singleton"
+
+    ^ self instance.
+
+    "Modified: / 27-11-2011 / 15:30:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Manager methodsFor:'accessing'!
+
+infoForClass: class
+
+    | info |
+
+    accessLock critical:[
+        info := self basicInfoForClass: class.
+    ].
+    ^info
+
+    "Created: / 27-11-2011 / 16:15:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+infoForClassOrNil: class
+
+    ^classes at: class name ifAbsent: nil
+
+    "Created: / 27-11-2011 / 17:15:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Manager methodsFor:'accessing-private'!
+
+basicInfoForClass: class
+
+    class isNil ifTrue:[^nil].
+
+    ^classes at: class name ifAbsentPut:[
+        ClassInfo new
+            setManager: self
+            className: class name
+    ].
+
+    "Created: / 27-11-2011 / 16:47:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Manager methodsFor:'change & update'!
+
+update:what with:param from:sender
+    "Invoked when an object that I depend upon sends a change notification."
+
+    UserPreferences current smallSenseBackgroundTypingEnabled ifFalse:[ ^ self ].
+
+    sender ~~ Smalltalk ifTrue:[
+        super update:what with:param from:sender.
+        ^self.
+    ].
+
+    what == #methodInClass ifTrue:[
+        "/ If this is anonymous class, do not bother...        
+
+        | nm |
+
+        nm := param first name.
+        (nm isSymbol and:[ Smalltalk includesKey: nm ]) ifTrue:[
+            self updateInfoForMethod: (param first >> param second).
+        ].
+        ^self.
+    ].
+    
+
+"/    Transcript show: 'SmallSense: Smalltalk changed: ', what , ' with: ', param printString.
+
+    "Modified: / 18-03-2014 / 12:27:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Manager methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    classes := Dictionary new.
+    accessLock := Semaphore forMutualExclusion.
+    updater := BackgroundQueueProcessingJob 
+                    named: 'SmallSense background updater' 
+                    on: [:classOrMethod|self delayedUpdateInfoForClassOrMethod: classOrMethod].
+    updater priority: Processor userBackgroundPriority - 1.
+
+    UserPreferences current smallSenseEnabled ifTrue:[
+        Smalltalk addDependent: self.
+    ].
+    seqno := 0
+
+    "Modified: / 22-10-2013 / 10:56:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+release
+    "Invoked when a new instance is created."
+
+    classes := nil.
+    accessLock := Semaphore forMutualExclusion.
+    updater stopAndRemoveAll.
+
+    UserPreferences current smallSenseEnabled ifTrue:[
+        Smalltalk removeDependent: self.
+    ].
+
+    "Created: / 21-11-2014 / 17:36:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Manager methodsFor:'updating'!
+
+updateInfoForClass: class
+
+    | info |
+
+    class programmingLanguage isSmalltalk ifFalse:[ ^ self ].
+    info := self infoForClassOrNil: class.
+    (info isNil or:[(info seqno ? 0) < (seqno - 100)]) ifTrue:[
+        updater add: class
+    ].
+    seqno := seqno == SmallInteger maxVal ifTrue: [1] ifFalse:[seqno + 1]
+
+    "Created: / 27-11-2011 / 17:46:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 22-10-2013 / 11:38:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateInfoForMethod: method
+
+    | info |
+
+    method programmingLanguage isSmalltalk ifFalse:[ ^ self ].
+    info := self basicInfoForClass: method mclass.
+    info isNil ifTrue:[
+        updater add: method mclass
+    ] ifFalse:[
+        updater add: method
+    ]
+
+    "Created: / 28-11-2011 / 19:30:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Manager methodsFor:'updating-delayed'!
+
+delayedUpdateInfoForClass: class
+
+    | superclass info instVarNames instVarTypes probe nprobed sourceStream |
+
+    superclass := class superclass.
+    superclass notNil ifTrue:[self updateInfoForClass: superclass].
+    info := self infoForClass: class.
+    info isErrorneous ifTrue:[ ^ self ].
+    info seqno: seqno.
+    [
+        instVarNames := class allInstVarNames.
+        instVarTypes := instVarNames collect: [:instvar | info infoForInstvar: instvar ]. 
+        "/ Check for the source stream - if none, then do not add methods (one cannot
+        "/ infer types without a source anyway  and mark the class errorneous...
+        [ 
+            sourceStream := class sourceStream.
+        ] on: Error do:[ 
+            sourceStream := nil.
+        ].
+        sourceStream isNil ifTrue:[ 
+            info errorneous: true.
+            ^ self.
+        ].
+        class methodsDo:[:mthd|updater add:mthd].
+
+        probe := [:instance |
+            instVarTypes withIndexDo: [:instVarType :i | 
+                instVarType union: ((Type withClass: (instance instVarAt: i) class) type trustfullness: 70). 
+            ].
+            nprobed := nprobed + 1.
+            nprobed > 100 ifTrue:[
+                "/ Probe at most 100 instancess
+                ^ self
+            ].   
+        ].
+        nprobed := 0.
+        class allInstancesDo: probe.
+        "/ Maube an abstract class?
+        nprobed < 100 ifTrue:[ 
+            class allSubInstancesDo: probe
+        ].
+    ] on: Error do:[:ex |  
+        info errorneous: true.  
+        Logger error:'Error when infering instvars for %1: %2' with: class name with: ex description
+    ]
+
+    "Created: / 27-11-2011 / 18:04:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-11-2014 / 17:17:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+delayedUpdateInfoForClassOrMethod: classOrMethod
+    | currentThread |
+
+    currentThread := Processor activeProcess.
+    updaterThread ~~ currentThread ifTrue:[ 
+        updaterThread := currentThread.
+        updaterThread addExitAction:[ 
+            updater stopAndRemoveAll.
+        ].
+    ].
+
+    [
+        classOrMethod isBehavior ifTrue:[
+           self delayedUpdateInfoForClass: classOrMethod.
+        ].
+        classOrMethod isMethod ifTrue:[
+           self delayedUpdateInfoForMethod: classOrMethod.
+        ]
+    ] on: Error do:[:ex|
+        Logger error: 'Error when infering for %1: %2' with: classOrMethod with: ex description.
+    ]
+
+    "Created: / 27-11-2011 / 18:01:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-11-2014 / 17:39:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+delayedUpdateInfoForMethod: method
+
+    | inferencer |
+
+    [
+        method mclass isNil ifTrue:["Obsolete method" ^ self ].
+        method mclass programmingLanguage isSmalltalk ifFalse: [ ^ self ].
+    "/    Transcript showCR: 'SmallSense: updating info for: ', method printString.
+        inferencer := SmalltalkInferencer forMethod: method.
+        inferencer process.
+    ] on: Error do:[:ex |  
+        Logger error:'Error when infering for method %1: %2' with: method printString with: ex description
+    ]
+
+    "Created: / 27-11-2011 / 18:06:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 21-11-2014 / 16:55:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Manager class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__MethodBindingPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,117 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#MethodBindingPO
+	instanceVariableNames:'binding'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java-Interface-PO'
+!
+
+!MethodBindingPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!MethodBindingPO methodsFor:'accessing'!
+
+binding
+    ^ binding
+!
+
+binding:b
+    binding := b.
+!
+
+label
+    "Return a text to be displayed. The label may be cached
+     `label` instvar."
+
+    label isNil ifTrue:[
+        | descriptor |
+
+        descriptor := binding signature.
+        label := JavaMethod specTextFromSignature:descriptor in: nil withName: binding selector isConstructor: binding isConstructor.   
+
+
+"/        | parameters |
+"/
+"/        label := String streamContents: [ :s |
+"/            s nextPutAll: binding selector.
+"/            s nextPut: $(.
+"/            parameters := binding parameters.
+"/            parameters notEmptyOrNil ifTrue:[ 
+"/                s nextPutAll: parameters first displayString.
+"/                parameters size > 1 ifTrue:[ 
+"/                    1 to: parameters size do:[:i |  
+"/                        s nextPutAll: ', '.
+"/                        s nextPutAll: (parameters at: i) displayString.
+"/                    ]
+"/                ].
+"/            ].
+"/            s nextPut: $).
+"/        ]
+    ].
+    ^ label
+
+    "Created: / 13-08-2014 / 22:33:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage:aProgrammingLanguage
+    ^ binding selector , '()'
+
+    "Created: / 13-08-2014 / 22:39:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodBindingPO methodsFor:'testing'!
+
+isSmallSenseMethodBindingPO
+    ^ true
+
+    "Created: / 13-08-2014 / 22:44:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodBindingPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__MethodInfo.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,85 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Info subclass:#MethodInfo
+	instanceVariableNames:'classInfo selector returnType'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types-Info'
+!
+
+!MethodInfo class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!MethodInfo class methodsFor:'instance creation'!
+
+forClassInfo: clsInfo selector: sel
+
+    ^self new
+        setClassInfo: clsInfo selector: sel;
+        yourself
+
+    "Created: / 27-11-2011 / 16:37:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodInfo methodsFor:'initialization'!
+
+setManager: mgr classInfo: clsInfo selector: sel
+
+    manager := mgr.
+    classInfo := clsInfo.
+    selector := sel.
+
+    "Created: / 29-11-2011 / 15:58:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodInfo class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__MethodKeywordRestPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,127 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+MethodPO subclass:#MethodKeywordRestPO
+	instanceVariableNames:'keywords'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!MethodKeywordRestPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!MethodKeywordRestPO class methodsFor:'accessing'!
+
+icon
+    "This resource specification was automatically generated
+     by the ImageEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the ImageEditor may not be able to read the specification."
+
+    "
+     self icon inspect
+     ImageEditor openOnClass:self andSelector:#icon
+     Icon flushCachedIcons
+    "
+
+    <resource: #image>
+
+    ^Icon
+        constantNamed:'SmallSense::MethodKeywordRestPO icon'
+        ifAbsentPut:[(Depth1Image new) width:13; height:11; bits:(ByteArray fromPackedString:'@@H@@@@@@@@@@@@@@@P@@@@E@@@@@0@a') ; colorMapFromArray:#[0 0 0 255 255 255]; mask:((Depth1Image new) width:13; height:11; bits:(ByteArray fromPackedString:'@@\@A0@G@@\@A0@GY&]&Y0@G@@\@A0@a') ; yourself); yourself]
+! !
+
+!MethodKeywordRestPO methodsFor:'accessing'!
+
+icon
+    ^ self class icon
+!
+
+keywords
+    ^ keywords
+!
+
+keywords:something
+    keywords := something.
+!
+
+label
+
+    label isNil ifTrue:[
+        label := keywords.
+    ].
+    ^ label
+
+    "Created: / 08-04-2014 / 21:08:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage: language
+
+    "/ This PO is only valid for Smalltalk language...
+    self assert: language isSmalltalk.
+
+    ^ String 
+        fromStringCollection: (keywords tokensBasedOn: $:)
+        separatedBy: ':  '.
+
+    "Created: / 08-04-2014 / 21:10:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodKeywordRestPO methodsFor:'initialization'!
+
+initializeWithClasses: anArray"Of Classes" selector: aSymbol prefix: aString 
+    selector := aSymbol.
+    classes := anArray.
+    keywords := (aSymbol copyFrom: aString size + 1)
+
+    "Created: / 20-05-2014 / 10:44:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodKeywordRestPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__MethodPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,204 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#MethodPO
+	instanceVariableNames:'selector classes'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!MethodPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!MethodPO methodsFor:'accessing'!
+
+classes
+    ^ classes
+!
+
+cursorColumnAfterComplete
+
+    | idx |
+    idx := self label indexOf: $:.
+    ^idx == 0 ifTrue:[self label size + 1] ifFalse:[idx + 1].
+
+    "Created: / 05-04-2011 / 17:08:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 11:43:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+cursorColumnAfterCompleteForLanguage: language
+    | stringToComplete idx |
+
+    stringToComplete := self stringToCompleteForLanguage: language.
+    language  isSmalltalk  ifTrue:[
+        idx := stringToComplete indexOf: $:.
+        ^idx == 0 ifTrue:[stringToComplete size] ifFalse:[idx].
+    ].
+    ((language askFor: #isJava) or:[language askFor: #isGroovy]) ifTrue:[
+        ^ (stringToComplete at: stringToComplete size - 1) isSeparator
+            ifTrue:[stringToComplete size- 2]
+            ifFalse:[stringToComplete size]
+    ].
+
+    ^ stringToComplete size + 1.
+
+    "Created: / 03-10-2013 / 16:50:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-10-2013 / 12:30:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hint
+    classes size == 1 ifTrue:[ 
+        ^ classes anElement nameWithoutNameSpacePrefix.
+    ].
+    classes size < 3 ifTrue:[ 
+        ^ (classes collect:[:each | each nameWithoutPrefix ]) asArray asStringWith:' , '.
+    ].
+    ^ '%1 implementors' bindWith: classes size.
+
+    "Created: / 20-05-2014 / 12:27:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-01-2015 / 19:15:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+    label isNil ifTrue:[
+        | someClass |
+
+        someClass := classes anElement.
+        label := selector.
+        someClass programmingLanguage isSmalltalk ifFalse:[
+            label := (someClass compiledMethodAt: selector) printStringForBrowserWithSelector: selector.
+        ]
+    ].
+    ^ label
+
+    "Created: / 07-04-2011 / 09:56:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 10:28:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selector
+    ^ selector
+!
+
+stringToCompleteForLanguage: language
+    | someClass |
+
+    someClass := classes anElement.
+    someClass isJavaClass ifTrue:[
+        | method |
+
+        method := someClass compiledMethodAt: selector.
+        language isSmalltalk  ifTrue:[          
+            ^ selector upTo: $(
+        ].
+        ((language askFor: #isJava) or:[language askFor: #isGroovy]) ifTrue:[
+            | selector |
+
+            selector := (method selector upTo: $().
+            selector = '<init>' ifTrue:[ 
+                selector := someClass lastName.
+            ].
+            selector := selector , (method numArgs == 0 ifTrue:['()'] ifFalse:['(  )']).
+            ^ selector
+        ].
+    ].
+    ^selector isKeyword ifTrue:[
+        String streamContents: [:s | selector keywords do:[:kw | s nextPutAll: kw; space; space ] ]
+    ] ifFalse:[ 
+        selector
+    ].
+
+    "Created: / 02-10-2013 / 02:33:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-03-2015 / 10:43:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodPO methodsFor:'accessing-private'!
+
+subject
+    "Return the real object for which the receiver
+     is a presentor.
+     
+     For internal usage only."
+
+    classes size ~~ 1 ifTrue:[ 
+        ^ classes collect:[ :cls | cls compiledMethodAt: selector ]
+    ].
+    ^ classes anElement compiledMethodAt: selector
+
+    "Created: / 20-06-2014 / 11:11:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-01-2015 / 16:20:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodPO methodsFor:'initialization'!
+
+initializeWithClass: aClass selector: aSymbol
+    ^ self initializeWithClasses: (Array with: aClass) selector: aSymbol
+
+    "Created: / 20-05-2014 / 10:32:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+initializeWithClasses: anArray"Of Classes" selector: aSymbol 
+    selector := aSymbol.
+    classes := anArray
+
+    "Created: / 20-05-2014 / 10:32:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 11:34:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodPO methodsFor:'testing'!
+
+isSmallSenseMethodPO
+    ^ true
+! !
+
+!MethodPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__MethodSearchDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,132 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSearchDialog subclass:#MethodSearchDialog
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!MethodSearchDialog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!MethodSearchDialog class methodsFor:'interface specs-content'!
+
+optionsPaneSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::ClassSearchDialog andSelector:#optionsPaneSpec
+     SmallSense::ClassSearchDialog new openInterface:#optionsPaneSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: optionsPaneSpec
+       window: 
+      (WindowSpec
+         label: 'Search Options...'
+         name: 'Search Options...'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 634 25)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (VerticalPanelViewSpec
+             name: 'Options'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             horizontalLayout: fit
+             verticalLayout: fit
+             horizontalSpace: 3
+             verticalSpace: 3
+             component: 
+            (SpecCollection
+               collection: (
+                (CheckBoxSpec
+                   label: 'Match fully qualified class names'
+                   name: 'CheckBox1'
+                   model: matchFullyQualifiedClassNameHolder
+                   extent: (Point 634 25)
+                 )
+                )
+              
+             )
+           )
+          )
+        
+       )
+     )
+! !
+
+!MethodSearchDialog methodsFor:'accessing-defaults'!
+
+defaultProcessorClass
+    "superclass SmallSense::AbstractListDialog says that I am responsible to implement this method"
+
+    ^ ImplementorSearchProcessor
+
+    "Created: / 12-12-2014 / 23:21:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+defaultTitle
+    ^ (resources string: 'Search Method...')
+
+    "Created: / 05-05-2014 / 23:39:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MethodSearchDialog methodsFor:'initialization'!
+
+initialize  
+    super initialize.
+    processor := ImplementorSearchProcessor new.
+
+    "Created: / 13-12-2014 / 08:46:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__Navigator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,192 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSearchDialog subclass:#Navigator
+	instanceVariableNames:'steps'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!Navigator class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!Navigator class methodsFor:'opening'!
+
+open
+    | result |    
+
+    result := self new open.
+    result isBehavior ifTrue:[ 
+        UserPreferences current systemBrowserClass openInClass:result selector: nil.
+        ^ self
+    ].
+    result isMethod ifTrue:[ 
+        UserPreferences current systemBrowserClass openInClass: result mclass selector: result selector.
+        ^ self
+    ].
+    result isCollection ifTrue:[ 
+        (result allSatisfy:[:e|e isMethod]) ifTrue:[ 
+            UserPreferences current systemBrowserClass 
+                browseMethods:result 
+                title:(self classResources string: 'Implementors of %1' with: result anElement selector storeString) 
+                sort:true.
+        ].
+        ^ self
+    ].
+    ^ self
+
+    "Created: / 25-01-2015 / 12:46:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 11:13:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Navigator methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+    "Invoked when an object that I depend upon sends a change notification."
+
+    changedObject == matchingObjectsSelectionHolder ifTrue:[
+        self updateMextSearchStepVisibility.
+    ].
+    ^ super update:something with:aParameter from:changedObject
+
+    "Created: / 23-01-2015 / 22:21:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateMextSearchStepVisibility
+    "raise an error: this method should be implemented (TODO)"
+
+    | selection |
+
+    selection := self matchingObjectsSelection.
+    matchingObjectsMultiselect ifTrue:[ 
+        selection := selection size == 1 ifTrue:[ selection anElement ] ifFalse:[ nil ]
+    ].
+    selection notNil ifTrue:[ 
+        self nextSearchStepVisibleHolder value: (processor canDoNextStepFor: selection)
+    ] ifFalse:[ 
+        self nextSearchStepVisibleHolder value: false.
+    ].
+
+    "Created: / 23-01-2015 / 22:21:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Navigator methodsFor:'change & update-background'!
+
+updateMatchingIgnorePattern
+    steps size == 1 ifTrue:[
+        ^ super updateMatchingIgnorePattern 
+    ].
+    self enqueueDelayedUpdateMatchingObjectPOs: (self matchingObjectPOsForPattern: nil)
+
+    "Created: / 24-01-2015 / 00:50:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 08:58:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Navigator methodsFor:'event processing'!
+
+keyPressCursorRightInMatchingObjectsView
+   self nextSearchStepVisibleHolder value ifTrue:[ 
+       self step.
+       ^ true.
+   ].
+   ^ super keyPressCursorRightInMatchingObjectsView
+
+    "Created: / 23-01-2015 / 22:45:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Navigator methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    steps := OrderedCollection new: 3.
+    self push: 
+        (NavigatorStep for: 
+            (CompositeProcessor 
+                    with: ClassSearchProcessor new 
+                    with: ImplementorSearchProcessor new))
+        update: false.
+
+    "Created: / 10-01-2015 / 07:03:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-01-2015 / 00:25:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Navigator methodsFor:'private-steps'!
+
+push: aNavigatorStep
+    self push: aNavigatorStep update: true
+
+    "Created: / 23-01-2015 / 21:01:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-01-2015 / 00:24:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+push: aNavigatorStep update: update
+    steps addLast: aNavigatorStep.
+    processor := aNavigatorStep processor.
+    update ifTrue:[ 
+        self matchPatternHolder value: nil.
+    ].
+
+    "Created: / 24-01-2015 / 00:24:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 17:51:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+step
+    | selection step |
+
+    selection := self matchingObjectsSelection.
+    matchingObjectsMultiselect ifTrue:[ 
+        selection := selection size == 1 ifTrue:[ selection anElement ] ifFalse:[ nil ]
+    ].
+    step := NavigatorStep for: (processor processorForNextStepFor: selection).
+    self push: step.
+
+    "Created: / 23-01-2015 / 22:48:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Navigator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__NavigatorStep.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,74 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#NavigatorStep
+	instanceVariableNames:'processor'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!NavigatorStep class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!NavigatorStep class methodsFor:'instance creation'!
+
+for: anAbstractSearchProcessor
+    ^ self new initializeWithProcessor: anAbstractSearchProcessor
+
+    "Created: / 23-01-2015 / 21:00:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!NavigatorStep methodsFor:'accessing'!
+
+processor
+    ^ processor
+! !
+
+!NavigatorStep methodsFor:'initialization'!
+
+initializeWithProcessor: anAbstractSearchProcessor
+    processor := anAbstractSearchProcessor
+
+    "Created: / 23-01-2015 / 20:59:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__PO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,478 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+CompactHierarchicalItem subclass:#PO
+	instanceVariableNames:'label relevance context'
+	classVariableNames:'IconWidth'
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!PO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!PO class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    IconWidth := 16.
+
+    "Modified: / 18-09-2013 / 00:13:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO class methodsFor:'Instance creation'!
+
+forClass: aClass
+    ^ ClassPO new initializeWithClass: aClass
+
+    "Created: / 20-05-2014 / 09:56:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forClass: aClass selector: aSymbol
+    ^ MethodPO new initializeWithClass: aClass selector: aSymbol
+
+    "Created: / 20-05-2014 / 10:31:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forClasses: aCollection selector: aSymbol
+    ^ MethodPO new initializeWithClasses: aCollection selector: aSymbol
+
+    "Created: / 20-05-2014 / 10:33:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forClasses: aCollection selector: aSymbol prefix: aString
+    ^ aString notEmptyOrNil 
+        ifTrue: [ MethodKeywordRestPO new initializeWithClasses: aCollection selector: aSymbol prefix: aString ]
+        ifFalse:[ MethodPO new initializeWithClasses: aCollection selector: aSymbol ]
+
+    "Created: / 20-05-2014 / 10:43:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forFieldBinding: binding
+    ^ VariableBindingPO new binding: binding
+
+    "Created: / 14-08-2014 / 09:04:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forGlobalNamed: name
+    ^ VariablePO globalVariable: name
+
+    "Created: / 24-07-2014 / 16:50:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forInstanceVariableNamed: nm in: cls
+    ^ VariablePO instanceVariable: nm in: cls.
+
+    "Created: / 13-08-2014 / 21:27:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forLocalVariableBinding: binding
+    ^ VariableBindingPO new binding: binding
+
+    "Created: / 14-08-2014 / 09:04:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forLocalVariableNamed: nm
+    ^ VariablePO variable: nm
+
+    "Created: / 12-08-2014 / 10:40:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forPackage:aSymbol
+    ^ PackagePO new initializeWithPackage: aSymbol
+
+    "Created: / 02-10-2014 / 00:01:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+subject: anObject
+    <resource: #obsolete>
+
+    ^self new subject: anObject
+
+    "Created: / 06-04-2011 / 21:01:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO class methodsFor:'instance creation-java'!
+
+forMethodBinding: binding
+    ^ MethodBindingPO new binding: binding
+
+    "Created: / 13-08-2014 / 22:24:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO methodsFor:'accessing'!
+
+context
+    ^ context
+!
+
+context:something
+    something notNil ifTrue:[
+        context := something.
+    ].
+
+    "Modified: / 17-10-2013 / 01:16:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+cursorColumnAfterCompleteForLanguage: language
+    "Answers a cursor column after completion. The number returned
+     is relative to the start of the text being replaced"
+
+    ^ (self stringToCompleteForLanguage: language) size
+
+    "Created: / 03-10-2013 / 16:49:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 07:48:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hint
+    "Return a hint text to be displayed in gray after a label
+     (if there's space). If nil is returned, no hint is shown"
+
+    ^ nil
+
+    "Created: / 20-05-2014 / 11:52:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+icon
+
+    ^nil
+
+    "Created: / 04-04-2011 / 17:25:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Return a text to be displayed. The label may be cached
+     `label` instvar."
+
+    ^ self subclassResponsibility
+
+    "Created: / 07-04-2011 / 09:55:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 11:30:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+name
+    <resource: #obsolete>
+
+    self obsoleteMethodWarning.
+    ^ self label
+
+    "Modified: / 20-05-2014 / 11:36:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+name:aString
+    <resource: #obsolete>
+
+    self shouldNeverBeSent
+
+    "Modified: / 20-05-2014 / 11:36:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+relevance
+    "Return relevance value, i.e., how much likely is that this
+     is what user wants to complete.
+
+     Relevance is an integer between 1 (least relevant) and 
+     100 (most relevant)"
+
+    ^ relevance ? 1
+
+    "Modified: / 18-01-2014 / 22:41:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+relevance: anInteger
+    "Set the relevance value, i.e., how much likely is that this
+     is what user wants to complete.
+
+     Relevance is an integer between 1 (least relevant) and 
+     100 (most relevant)"
+
+    ^ relevance := anInteger.
+
+    "Modified: / 18-01-2014 / 22:41:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringAlreadyWritten
+    "Answers a string already written in the textview"    
+
+    ^ context wordBeforeCursor
+
+    "Created: / 20-10-2013 / 00:14:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToComplete
+    ^ self stringToCompleteForLanguage: context language.
+
+    "Created: / 05-04-2011 / 16:48:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-03-2014 / 23:10:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage: aProgrammingLanguage
+    "Answers a string to complete"
+
+    ^ self subclassResponsibility
+
+    "Created: / 02-10-2013 / 02:32:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 11:32:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+subject:anObject
+    <resource: #obsolete>
+
+    self error: 'Should no longer be sent'.
+
+    "Modified: / 20-05-2014 / 10:16:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO methodsFor:'accessing-private'!
+
+subject
+    "Return the real object for which the receiver
+     is a presentor.
+
+     For internal usage only."
+
+    ^ self subclassResponsibility
+
+    "Modified: / 20-06-2014 / 11:09:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO methodsFor:'completion'!
+
+insert
+    "Insert given completion item at cursor position"
+
+    | po stringToComplete stringAlreadyWritten stringToInsert textView |
+
+    po := self.
+    textView := context textView.
+    stringToComplete := po stringToCompleteForLanguage: context language.
+    stringAlreadyWritten := self stringAlreadyWritten.
+    stringToInsert := stringToComplete copyFrom: (stringAlreadyWritten size + 1).
+    textView isCodeView2 ifTrue:[textView := textView textView].
+    (stringToComplete startsWith: stringAlreadyWritten) ifTrue:[
+        context support 
+                electricInsert:stringToInsert
+                ignoreKeystrokes:stringToInsert.
+        textView cursorCol: textView cursorCol - stringToComplete size + (po cursorColumnAfterCompleteForLanguage: context language).
+    ] ifFalse:[
+       | startCol endCol |
+       textView undoableDo:[
+            endCol := textView cursorCol - 1.
+            startCol := textView cursorCol - stringAlreadyWritten size.
+            textView insertStringAtCursor: stringToComplete.
+            textView deleteFromLine:textView cursorLine col: startCol toLine:textView cursorLine col:endCol.
+        ].
+        textView cursorCol: startCol + (po cursorColumnAfterCompleteForLanguage: context language).
+
+    ].
+
+    "Created: / 17-10-2013 / 01:08:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:53:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO methodsFor:'displaying'!
+
+displayLabel:lab h:lH on:gc x:x y:y0 h:h isHighlightedAsSelected: highlighted
+    | cx hint hintW cy |
+
+    cx := x.
+
+"/    iconOrNil := self icon.
+"/    iconOrNil notNil ifTrue:[
+"/        iconOrNil displayOn: aGC x: cx y: y + (h / 2) - (iconOrNil height / 2).
+"/    ].
+"/    cx := cx + IconWidth.
+
+    "/ Display label
+    super displayLabel:lab h:lH on:gc x:cx y:y0 h:h isHighlightedAsSelected: highlighted.
+
+    "/ Display hint
+    hint := self hint.
+    hint notNil ifTrue:[ 
+        cx := cx + (lab widthOn: gc).
+        hintW := hint widthOn: gc.
+        "/ Check whether there's enougn space fit the hint
+        (gc width) > (cx + hintW + 10"spacing") ifFalse:[ 
+            hint isString ifFalse:[ 
+                "/ There's nothing to do for non-strings
+                ^ self 
+            ].
+            "/ Try to shorten the text.
+            hint := hint contractAtEndTo: ((gc width - cx - 10) // ('m' widthOn: gc)).
+            hint size < 6 ifTrue:[ 
+                "/ To short to be meaningfull, give up.
+                ^ self.
+            ].
+            hintW := hint widthOn: gc.
+            "/ Check again if it can fit...
+            (gc width) > (cx + hintW + 10"spacing") ifFalse:[ 
+                "/ Give up.
+                ^ self.
+            ]
+        ].
+
+        cx := gc width - hintW - 3"right padding".
+        cy := y0 - ((lH + 1 - h) // 2).    
+        (hint isString and:[hint isText not]) ifTrue:[ 
+            | savPaint |
+
+            cy := cy + (hint ascentOn:gc).   
+            savPaint := gc paint.
+            highlighted ifTrue:[
+                gc paint: (Color white).
+            ] ifFalse:[ 
+                gc paint: (Color gray: 40).
+            ].
+            hint displayOn:gc x: cx y:cy.  
+            gc paint: savPaint
+        ] ifFalse:[ 
+            hint isText ifTrue:[ 
+                cy := cy + (hint ascentOn:gc).   
+            ].
+            hint displayOn:gc x: cx y:cy.  
+        ].
+    ].
+
+    "Created: / 03-02-2015 / 05:34:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+displayOn:aGC x:x y:y h:h isHighlightedAsSelected: highlighted
+    | cx iconOrNil |
+
+    cx := x.
+
+    parent isNil ifTrue:[
+        iconOrNil := self icon.
+        iconOrNil notNil ifTrue:[
+            iconOrNil displayOn: aGC x: cx y: y + (h / 2) - (iconOrNil height / 2).
+        ].
+        cx := cx + IconWidth.
+    ].
+
+    super displayOn:aGC x:cx y:y h:h isHighlightedAsSelected: highlighted
+
+    "Created: / 05-02-2015 / 06:48:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+displayString
+    ^ self label
+
+    "Created: / 20-04-2012 / 18:19:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 11:34:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO methodsFor:'printing & storing'!
+
+printOn:aStream
+    "append a printed representation if the receiver to the argument, aStream"
+
+    super printOn:aStream.
+    aStream nextPut:$(.
+    aStream nextPutAll:self label.
+    aStream nextPut:$).
+
+    "Modified: / 13-08-2014 / 01:53:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO methodsFor:'queries'!
+
+startsWith: prefix
+
+    ^self stringToComplete startsWith: prefix
+
+    "Created: / 26-11-2011 / 19:25:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PO methodsFor:'testing'!
+
+isSmallSenseClassPO
+    ^ false
+!
+
+isSmallSenseConstantPO
+    ^ false
+!
+
+isSmallSenseMethodBindingPO
+    "return false here; to be redefined in subclass(es)"
+
+    ^ false
+!
+
+isSmallSenseMethodPO
+    ^ false
+!
+
+isSmallSensePluggablePO
+    ^ false
+!
+
+isSmallSenseSnippetPO
+    ^ false
+!
+
+isSmallSenseVariableBindingPO
+    "return false here; to be redefined in subclass(es)"
+
+    ^ false
+!
+
+isSmallSenseVariablePO
+    ^ false
+! !
+
+!PO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
+
+PO initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__PackagePO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,125 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#PackagePO
+	instanceVariableNames:'package packageDefinition isJava'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!PackagePO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!PackagePO methodsFor:'accessing'!
+
+icon
+    ^ ToolbarIconLibrary smallYellowPackageIcon
+
+    "Created: / 06-05-2014 / 00:09:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Return a text to be displayed. The label may be cached
+     `label` instvar."
+
+    ^ package
+
+    "Created: / 19-06-2014 / 12:04:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+name
+    ^ package 
+
+    "Created: / 06-05-2014 / 00:01:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+package
+    ^ package
+!
+
+packageDefinition
+    packageDefinition isNil ifTrue:[
+        packageDefinition := ProjectDefinition definitionClassForPackage:package.
+    ].
+    ^ packageDefinition
+
+    "Created: / 06-05-2014 / 00:05:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PackagePO methodsFor:'accessing-private'!
+
+subject
+    "Return the real object for which the receiver
+     is a presentor.
+     
+     For internal usage only."
+
+    ^ package
+
+    "Created: / 20-06-2014 / 11:11:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PackagePO methodsFor:'initialization'!
+
+initializeWithPackage: aStringOrSymbol
+    package := aStringOrSymbol.
+    isJava := false.
+
+    "Created: / 19-06-2014 / 12:02:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PackagePO methodsFor:'testing'!
+
+isSmallSensePackagePO
+    ^ true
+
+    "Created: / 05-05-2014 / 23:50:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PackagePO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__PackageSelectDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSelectDialog subclass:#PackageSelectDialog
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!PackageSelectDialog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!PackageSelectDialog methodsFor:'accessing - private'!
+
+matchingObjectForString: aString
+    "Creates a new object from given string. Called only when
+     #canCreateMatchingObjectFromString: returns true"
+
+    ^ aString asSymbol
+
+    "Created: / 23-06-2014 / 15:25:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PackageSelectDialog methodsFor:'accessing-defaults'!
+
+defaultTitle
+    ^ (resources string: 'Select Package...')
+
+    "Created: / 13-12-2014 / 12:57:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PackageSelectDialog methodsFor:'queries'!
+
+canCreateMatchingObjectFromString:string 
+    "Return true, a new object can be created with given string value"
+    
+    ^ string notNil and:[ string allSatisfy:[:c | c isLetterOrDigit or:[ '_:/' includes:c ] ] ]
+
+    "Created: / 23-06-2014 / 15:15:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-01-2015 / 07:23:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canSelect:selection
+    ^ selection askFor: #isSmallSensePackagePO
+
+    "Created: / 05-05-2014 / 23:50:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PackageSelectDialog methodsFor:'searching'!
+
+matchingObjectPOsForPattern:pattern relax: level
+    | environment packages |
+
+    environment := self environment.
+    packages := Set new.
+
+    environment allClassesDo: [ :cls |
+        | pkg |
+
+        pkg := cls package.
+        ((pkg notNil and:[ pkg ~~ PackageId noProjectID and:[ (pkg startsWith: '__') not] ])
+            and:[(filter isNil or:[ filter value: pkg ])
+            and:[pattern isNil or:[pattern match: pkg relax: level]]]) ifTrue:[ packages add: pkg ].
+    ].
+    environment allMethodsDo:[ :mth |
+        | pkg |
+
+        pkg := mth package.
+        ((pkg notNil and:[ pkg ~~ PackageId noProjectID and:[ (pkg startsWith: '__') not] ])
+            and:[(filter isNil or:[ filter value: pkg ])
+            and:[pattern isNil or:[pattern match: pkg relax: level]]]) ifTrue:[ packages add: pkg ].
+    ].
+    packages := packages asArray.
+    packages sort: [ :a :b | a < b ].
+    ^ packages collect:[ :e | PO forPackage: e ].
+
+    "Created: / 13-12-2014 / 08:42:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ParseTreeIndex.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,139 @@
+"
+ COPYRIGHT (c) 2006 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+OrderedCollection subclass:#ParseTreeIndex
+	instanceVariableNames:'tree source'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Index'
+!
+
+!ParseTreeIndex class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2006 by eXept Software AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+documentation
+"
+    For given parse tree, a ParseTreeIndex provides an
+    fast access to individual (leave) nodes by keeping
+    an index. Used by CodeView2 for various queries
+
+    Experimental
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!ParseTreeIndex methodsFor:'accessing'!
+
+atCharacterPosition: characterPosition
+    "Retrun entry at given character position or nil, if none"
+
+    | index element |
+
+    0"1" to:0 by:-1 do:[:d |
+        index := (self indexForInserting:characterPosition) - d.
+        index > self size ifTrue:[^nil].
+        element := self at:index ifAbsent:nil.
+        element notNil ifTrue:[
+            (characterPosition between: element start and: element stop) ifTrue:[^element].
+        ].
+        index + 1 > self size ifTrue:[^nil].
+        element := self at:index + 1 ifAbsent:nil.
+        element notNil ifTrue:[
+            (characterPosition between: element start and: element stop) ifTrue:[^element].
+        ].
+
+    ].
+        ^nil
+
+    "Created: / 20-10-2013 / 01:02:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+source
+    ^ source
+!
+
+source:something
+    source := something.
+!
+
+tree
+    ^ tree
+!
+
+tree:aParseNode
+    tree := aParseNode.
+! !
+
+!ParseTreeIndex methodsFor:'inspecting'!
+
+inspector2TabParseTreeInspector
+    ^ (self newInspector2Tab)
+        label:'Parse Tree';
+        priority:35;
+        application:
+            [
+                SmallSense::ParseTreeInspector new node:tree source:source
+            ];
+        yourself
+
+    "Created: / 09-04-2014 / 09:31:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-04-2014 / 08:58:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+inspector2Tabs
+    ^ super inspector2Tabs , #(inspector2TabParseTreeInspector)
+
+    "Created: / 09-04-2014 / 09:32:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-04-2014 / 08:47:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeIndex methodsFor:'utilities'!
+
+newElementFor: aParseNode
+
+    ^(ParseTreeIndexEntry new node: aParseNode)
+
+    "Created: / 16-02-2012 / 21:00:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeIndex class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ParseTreeIndexEntry.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,283 @@
+"
+ COPYRIGHT (c) 2010 by Jan Vrany, SWING Research Group. CTU in Prague
+              All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the 'Software'), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Magnitude subclass:#ParseTreeIndexEntry
+	instanceVariableNames:'next prev start stop node'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Index'
+!
+
+!ParseTreeIndexEntry class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2010 by Jan Vrany, SWING Research Group. CTU in Prague
+              All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the 'Software'), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+"
+! !
+
+!ParseTreeIndexEntry methodsFor:'accessing'!
+
+assigned
+    ^false
+
+    "Created: / 01-07-2013 / 21:53:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+firstElementInChain
+    |first prev|
+
+    first := self.
+    [ (prev := first previousElement) notNil ] whileTrue:[
+        first := prev.
+    ].
+    ^ first
+
+    "Created: / 21-08-2011 / 09:51:35 / cg"
+!
+
+name
+    ^node isVariable ifTrue:[node name] ifFalse:[nil]
+
+    "Created: / 01-07-2013 / 21:56:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-10-2013 / 12:22:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+next
+    ^ next
+!
+
+next:aSyntaxElement
+    next := aSyntaxElement.
+    next prev: self.
+
+    "Modified: / 14-02-2010 / 17:44:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+nextElement
+    ^ next
+
+    "Created: / 21-08-2011 / 09:47:11 / cg"
+!
+
+nextElement:aSyntaxElement
+    next := aSyntaxElement.
+    next prev: self.
+
+    "Modified: / 14-02-2010 / 17:44:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 21-08-2011 / 09:47:15 / cg"
+!
+
+node
+    ^ node
+!
+
+node:something
+    node := something.
+!
+
+prev
+    ^ prev
+!
+
+prev:aSyntaxElement
+    prev := aSyntaxElement.
+!
+
+previousElement
+    ^ prev
+
+    "Created: / 21-08-2011 / 09:47:23 / cg"
+!
+
+previousElement:aSyntaxElement
+    prev := aSyntaxElement.
+
+    "Created: / 21-08-2011 / 09:47:28 / cg"
+!
+
+start
+    ^ start notNil ifTrue:[start] ifFalse:[node startPosition]
+
+    "Modified: / 24-09-2013 / 03:01:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+start:something
+    start := something.
+!
+
+stop
+    ^ stop notNil ifTrue:[stop] ifFalse:[node endPosition]
+
+    "Modified: / 24-09-2013 / 03:01:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stop:something
+    stop := something.
+! !
+
+!ParseTreeIndexEntry methodsFor:'comparing'!
+
+< anObject
+
+    anObject isNumber ifTrue:[^self stop < anObject].
+    anObject class == self class ifFalse:[^false].
+
+    ^self stop < anObject start
+
+    "Created: / 14-02-2010 / 13:39:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+= anObject
+
+    anObject class == self class ifFalse:[^false].
+
+    ^self start == (anObject start) and:
+        [self stop == (anObject stop) and:
+            [self node class == (anObject node class)]].
+
+    "Created: / 14-02-2010 / 13:33:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hash
+
+    ^self start hash bitXor:[self stop hash bitXor:[node class hash]].
+
+    "Created: / 14-02-2010 / 13:30:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeIndexEntry methodsFor:'double dispatching'!
+
+lessFromInteger:anInteger
+
+    ^self stop < anInteger
+
+    "Created: / 14-02-2010 / 13:49:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeIndexEntry methodsFor:'printing & storing'!
+
+printOn:aStream
+    "append a printed representation if the receiver to the argument, aStream"
+
+    super printOn:aStream.
+    aStream nextPutAll:'('.
+    self start printOn: aStream.
+    aStream nextPutAll: ' - '.
+    self stop printOn: aStream.
+    aStream space.
+    node class name printOn: aStream.
+    aStream nextPut:$).
+
+    "Modified: / 21-08-2011 / 09:33:51 / cg"
+    "Modified: / 30-09-2013 / 09:12:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeIndexEntry methodsFor:'testing'!
+
+isClassVariable
+    ^ node isVariable and:[node isClassVariable]
+!
+
+isGlobal
+    ^ node isGlobal
+
+    "Created: / 24-09-2013 / 02:50:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isInstanceVariable
+    ^node isVariable and:[node isInstanceVariable]
+
+    "Created: / 01-07-2013 / 21:54:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isSelector
+    ^ node isSelector
+
+    "Created: / 21-08-2011 / 09:09:19 / cg"
+    "Modified: / 24-09-2013 / 02:57:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isSelf
+    ^ node isSelf
+
+    "Created: / 21-08-2011 / 09:31:20 / cg"
+    "Modified: / 16-02-2012 / 19:25:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isVariable
+    ^ node isVariable
+
+    "Created: / 21-08-2011 / 09:09:00 / cg"
+    "Modified: / 16-02-2012 / 19:24:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isVariableOrSelf
+    ^ self isVariable or:[self isSelf]
+
+    "Created: / 21-08-2011 / 09:31:33 / cg"
+! !
+
+!ParseTreeIndexEntry class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/smallsense/SmallSense__ParseTreeIndexEntry.st,v 1.2 2015-02-06 08:56:30 stefan Exp $'
+!
+
+version_CVS
+    ^ '$Path: stx/goodies/smallsense/SmallSense__ParseTreeIndexEntry.st, Version: 1.0, User: stefan, Time: 2015-02-06T09:56:01.970+01$'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ParseTreeInspector.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,788 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+ApplicationModel subclass:#ParseTreeInspector
+	instanceVariableNames:'classHolder selectorHolder methodHolder nodeHolder sourceHolder
+		sourceView inspectorView'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface'
+!
+
+HierarchicalItem subclass:#ParseTreeItem
+	instanceVariableNames:'astNode ivarName'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:ParseTreeInspector
+!
+
+!ParseTreeInspector class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ParseTreeInspector class methodsFor:'instance creation'!
+
+node: node source: source
+
+    ^self new node: node source: source
+
+    "Created: / 14-09-2011 / 17:25:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'interface opening'!
+
+openOnClass: class selector: selector
+
+    ^self new
+        class: class selector: selector;
+        open
+
+    "
+        SmallSenseParseNodeInspector 
+            openOnClass: self
+            selector: #openOnClass:selector: 
+    "
+
+    "Created: / 26-11-2011 / 12:30:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+openOnNode: node source: source
+
+    ^self new
+        node: node source: source;
+        open
+
+    "Created: / 25-08-2013 / 10:28:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'interface specs'!
+
+inspectorTabSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:Tools::ParseNodeInspector andSelector:#inspectorTabSpec
+     Tools::ParseNodeInspector new openInterface:#inspectorTabSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+     #(FullSpec
+        name: inspectorTabSpec
+        window: 
+       (WindowSpec
+          label: 'InspectorTab'
+          name: 'InspectorTab'
+          min: (Point 10 10)
+          bounds: (Rectangle 0 0 300 300)
+        )
+        component: 
+       (SpecCollection
+          collection: (
+           (NonScrollableArbitraryComponentSpec
+              name: 'InspectorView'
+              layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+              component: nodeInspectorView
+            )
+           )
+         
+        )
+      )
+
+    "Modified: / 09-04-2014 / 22:29:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+sourceTabSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::ParseNodeInspector andSelector:#sourceTabSpec
+     SmallSense::ParseNodeInspector new openInterface:#sourceTabSpec
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: sourceTabSpec
+       window: 
+      (WindowSpec
+         label: 'SourceTab'
+         name: 'SourceTab'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 300 300)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (TextEditorSpec
+             name: 'SourceView'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             model: sourceHolder
+             hasHorizontalScrollBar: true
+             hasVerticalScrollBar: true
+             isReadOnly: true
+             showingCode: true
+             hasKeyboardFocusInitially: false
+             postBuildCallback: postBuildSourceView:
+             viewClassName: 'CodeView'
+           )
+          )
+        
+       )
+     )
+!
+
+windowSpec
+    ^ self windowSpecWithInspector
+
+    "Modified: / 09-04-2014 / 22:27:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+windowSpecWithInspector
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::ParseNodeInspector andSelector:#windowSpecWithInspector
+     SmallSense::ParseNodeInspector new openInterface:#windowSpecWithInspector
+    "
+
+    <resource: #canvas>
+
+    ^ 
+    #(FullSpec
+       name: windowSpecWithInspector
+       window: 
+      (WindowSpec
+         label: 'Parse Tree Inspector'
+         name: 'Parse Tree Inspector'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 630 322)
+       )
+       component: 
+      (SpecCollection
+         collection: (
+          (VariableHorizontalPanelSpec
+             name: 'QueryTreeAndSourcePanel'
+             layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+             showHandle: true
+             snapMode: both
+             handlePosition: right
+             component: 
+            (SpecCollection
+               collection: (
+                (HierarchicalListViewSpec
+                   name: 'QueryTree'
+                   model: selectionHolder
+                   menu: queryTreeMenu
+                   hasHorizontalScrollBar: true
+                   hasVerticalScrollBar: true
+                   listModel: parseTree
+                   useIndex: false
+                   highlightMode: line
+                   useDefaultIcons: false
+                 )
+                (NoteBookViewSpec
+                   name: 'NoteBook'
+                   menu: tabList
+                 )
+                )
+              
+             )
+             handles: (Any 0.3 1.0)
+           )
+          )
+        
+       )
+     )
+!
+
+windowSpecWithoutInspector
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSenseParseNodeInspector andSelector:#windowSpec
+     SmallSenseParseNodeInspector new openInterface:#windowSpec
+     SmallSenseParseNodeInspector open
+    "
+
+    <resource: #canvas>
+
+    ^ 
+     #(FullSpec
+        name: windowSpec
+        window: 
+       (WindowSpec
+          label: 'Parse Tree Inspector'
+          name: 'Parse Tree Inspector'
+          min: (Point 10 10)
+          bounds: (Rectangle 0 0 630 322)
+        )
+        component: 
+       (SpecCollection
+          collection: (
+           (VariableHorizontalPanelSpec
+              name: 'QueryTreeAndSourcePanel'
+              layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+              showHandle: true
+              snapMode: both
+              handlePosition: right
+              component: 
+             (SpecCollection
+                collection: (
+                 (HierarchicalListViewSpec
+                    name: 'QueryTree'
+                    model: selectionHolder
+                    menu: queryTreeMenu
+                    hasHorizontalScrollBar: true
+                    hasVerticalScrollBar: true
+                    listModel: parseTree
+                    useIndex: false
+                    highlightMode: line
+                    useDefaultIcons: false
+                  )
+                 (UISubSpecification
+                    name: 'SourceSoec'
+                    minorKey: sourceTabSpec
+                  )
+                 )
+               
+              )
+              handles: (Any 0.3 1.0)
+            )
+           )
+         
+        )
+      )
+
+    "Created: / 09-04-2014 / 22:26:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'list specs'!
+
+tabList
+    "This resource specification was automatically generated
+     by the TabListEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the TabListEditor may not be able to read the specification."
+
+    "
+     TabListEditor new openOnClass: self andSelector:#tabList
+    "
+
+    <resource: #tabList>
+
+    ^     #(
+       (TabItem
+          label: 'Source'
+          minorKey: sourceTabSpec
+          createNewBuilder: false
+        )
+       (TabItem
+          label: 'Node'
+          minorKey: inspectorTabSpec
+          createNewBuilder: false
+        )
+       )
+     
+      collect:[:aTab| TabItem new fromLiteralArrayEncoding:aTab ]
+! !
+
+!ParseTreeInspector class methodsFor:'menu specs'!
+
+queryTreeMenu
+    "This resource specification was automatically generated
+     by the MenuEditor of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the MenuEditor may not be able to read the specification."
+
+    "
+     MenuEditor new openOnClass:XQuery::QueryInspectorUI andSelector:#queryTreeMenu
+     (Menu new fromLiteralArrayEncoding:(XQuery::QueryInspectorUI queryTreeMenu)) startUp
+    "
+
+    <resource: #menu>
+
+    ^
+     #(Menu
+	(
+	 (MenuItem
+	    label: 'Inspect AST node'
+	    itemValue: queryTreeMenuInspectAstNode
+	    translateLabel: true
+	  )
+	 )
+	nil
+	nil
+      )
+
+    "Created: / 12-04-2007 / 11:46:57 / janfrog"
+! !
+
+!ParseTreeInspector class methodsFor:'plugIn spec'!
+
+aspectSelectors
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this. If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "Return a description of exported aspects;
+     these can be connected to aspects of an embedding application
+     (if this app is embedded in a subCanvas)."
+
+    ^ #(
+        #model
+      ).
+
+! !
+
+!ParseTreeInspector methodsFor:'accessing'!
+
+class: class selector: selector
+    | mth source node parser |
+
+    mth := class >> selector.
+    mth isNil ifTrue:[
+        self error:'No such method'.
+        ^self.
+    ].
+    source := mth source.
+    parser := Parser parseMethod: source.
+    node := parser tree.
+
+    self node: node source: source.
+
+     "
+        SmallSenseParseNodeInspector 
+            openOnClass: SmallSenseParseNodeInspector
+            selector: #class:selector: 
+    "
+
+    "Created: / 15-02-2012 / 12:25:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+node: node source: source
+
+    self nodeHolder value: node.
+    self sourceHolder value: source.
+
+    "Created: / 14-09-2011 / 17:23:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selection
+
+    | item |
+    (item := self selectionHolder value) notNil ifTrue:[
+        ^item
+    ] ifFalse:[
+        ^nil
+    ]
+
+    "Created: / 12-04-2007 / 12:29:08 / janfrog"
+    "Created: / 26-11-2011 / 11:46:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector methodsFor:'aspects'!
+
+nodeHolder
+    "return/create the 'nodeHolder' value holder (automatically generated)"
+
+    nodeHolder isNil ifTrue:[
+        nodeHolder := ValueHolder new.
+    ].
+    ^ nodeHolder
+!
+
+nodeHolder:something
+    "set the 'nodeHolder' value holder (automatically generated)"
+
+    nodeHolder := something.
+!
+
+nodeInspectorView
+
+    inspectorView isNil ifTrue:[
+        inspectorView := InspectorView new
+    ].
+    ^ inspectorView
+
+    "Created: / 31-10-2007 / 12:20:02 / janfrog"
+    "Created: / 14-09-2011 / 17:24:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parseTree
+
+    ^self builder bindings at: #parseTree
+        ifAbsentPut:
+            [PluggableAdaptor on: self nodeHolder getter:
+                [:m|
+                | rootAstNodeItem rootAstNode hl |
+
+                rootAstNode := self nodeHolder value.
+
+                rootAstNodeItem := ParseTreeItem new
+                                            ivarName: 'AST';
+                                            astNode: rootAstNode;
+                                            yourself.
+
+
+                hl := HierarchicalList new
+                        root: rootAstNodeItem;
+                        showRoot: true;
+                        yourself.
+                rootAstNodeItem expand.
+                hl]]
+
+    "Created: / 28-03-2007 / 15:58:31 / janfrog"
+    "Modified: / 31-10-2007 / 12:11:46 / janfrog"
+    "Created: / 14-09-2011 / 17:24:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 10:19:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selectionHolder
+
+    ^self builder bindings at: #selectionHolder
+        ifAbsentPut:
+            [nil asValue
+                onChangeSend:#updateSourceViewSelection to:self;
+                onChangeSend:#updateInspectorView to:self;
+                yourself]
+
+    "Created: / 28-03-2007 / 16:46:30 / janfrog"
+    "Modified: / 31-10-2007 / 12:25:54 / janfrog"
+    "Created: / 14-09-2011 / 17:24:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-04-2014 / 09:35:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+sourceHolder
+    "return/create the 'sourceHolder' value holder (automatically generated)"
+
+    sourceHolder isNil ifTrue:[
+        sourceHolder := ValueHolder new.
+    ].
+    ^ sourceHolder
+!
+
+sourceHolder:something
+    "set the 'sourceHolder' value holder (automatically generated)"
+
+    sourceHolder := something.
+!
+
+tabList
+    "Generated by the TabListEditor"
+
+    |list|
+
+    (list := builder bindingAt:#tabList) isNil ifTrue:[
+	builder aspectAt:#tabList put:(list := self class tabList).
+    ].
+    ^ list
+
+    "Created: / 31-10-2007 / 12:21:18 / janfrog"
+! !
+
+!ParseTreeInspector methodsFor:'callbacks - post build'!
+
+postBuildSourceView: aView
+
+    sourceView := aView scrolledView.
+    sourceView cursorLineHolder addDependent: self.
+    sourceView cursorColHolder addDependent: self.
+
+    "Created: / 12-04-2007 / 12:28:14 / janfrog"
+    "Modified: / 10-04-2014 / 07:55:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+    "Invoked when an object that I depend upon sends a change notification."
+
+    sourceView notNil ifTrue:[
+        "/ cursor moved by user...
+        ((changedObject == sourceView cursorLineHolder)
+        or:[ changedObject == sourceView cursorColHolder ]) ifTrue:[
+            self updateSelectionFromCursor.
+            ^ self.
+        ].
+
+    ].
+    super update:something with:aParameter from:changedObject
+
+    "Modified: / 10-04-2014 / 07:57:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateInspectorView
+
+    inspectorView notNil ifTrue:[ 
+        | selection |
+
+        selection := self selection.
+        inspectorView inspect: (selection isNil ifTrue:[ nil ] ifFalse:[ selection node ])
+    ]
+
+    "Created: / 31-10-2007 / 12:25:25 / janfrog"
+    "Modified: / 10-04-2014 / 08:34:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSelectionFromCursor
+    | pos root selection |
+
+    pos := sourceView characterPositionOfCursor.
+    root := self parseTree value root.
+    selection := root leafNodeAt: pos.
+    selection notNil ifTrue:[ 
+        | item |
+
+        item := selection.
+        [ item notNil ] whileTrue:[ 
+            item expand.
+            item := item parent.
+        ].
+        self selectionHolder value: selection
+
+    ].
+
+    "Created: / 10-04-2014 / 07:57:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSourceViewSelection
+
+    | astNode parseNode startPosition stopPosition |
+
+    sourceView ifNil:[^self].
+    (astNode := self selection) ifNil:[^self].
+    (parseNode := astNode node) isNil ifTrue:[ ^ self ].
+
+    (startPosition := parseNode startPosition)
+        ifNil:[^sourceView unselect].
+    (stopPosition := parseNode endPosition)
+        ifNil:[^sourceView unselect].
+
+    "/ avoid cyclic update (from changed cursor)
+    "/ (which would deselect again)
+    sourceView cursorLineHolder withoutUpdating:self do:[
+        sourceView cursorColHolder withoutUpdating:self do:[   
+            sourceView selectFromCharacterPosition: startPosition to: stopPosition.
+            sourceView makeCursorVisible
+        ]
+    ]
+    "Created: / 12-04-2007 / 12:29:42 / janfrog"
+    "Modified: / 07-08-2014 / 10:21:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector methodsFor:'menu actions'!
+
+queryTreeMenuInspectAstNode
+
+    ^self selection node inspect
+
+    "Created: / 12-04-2007 / 11:47:48 / janfrog"
+    "Modified: / 26-11-2011 / 12:12:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector::ParseTreeItem class methodsFor:'documentation'!
+
+version
+    ^'$Header: /cvs/stx/stx/goodies/smallsense/SmallSense__ParseTreeInspector.st,v 1.2 2015-02-04 09:46:31 cg Exp $'
+! !
+
+!ParseTreeInspector::ParseTreeItem methodsFor:'accessing'!
+
+astNode
+    ^ astNode
+
+    "Created: / 28-03-2007 / 15:51:49 / janfrog"
+!
+
+astNode:anAstNode
+    astNode := anAstNode.
+
+    "Created: / 28-03-2007 / 15:51:49 / janfrog"
+!
+
+astNodeName
+
+    ^astNode class name
+
+    "Created: / 12-04-2007 / 11:29:57 / janfrog"
+    "Modified: / 31-10-2007 / 12:13:34 / janfrog"
+    "Modified: / 26-11-2011 / 10:47:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+children
+
+    children isNil ifTrue:[
+        children := OrderedCollection new.
+        astNode notNil ifTrue:[
+            astNode childNamesAndValuesDo:[:ivarName :astNode|
+                astNode notNil ifTrue:[
+                    children add: (self class new
+                                    ivarName: ivarName;
+                                    astNode: astNode;
+                                    parent: self)
+                ]
+            ].
+        ].
+    ].
+    ^children
+
+    "Created: / 28-03-2007 / 15:55:24 / janfrog"
+    "Modified: / 12-04-2007 / 11:35:24 / janfrog"
+    "Modified: / 07-08-2014 / 10:20:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+icon
+
+    ^nil
+
+    "Created: / 31-10-2007 / 12:14:52 / janfrog"
+    "Modified: / 26-11-2011 / 10:47:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+ivarName
+    ^ ivarName ? '?'
+
+    "Created: / 12-04-2007 / 11:29:28 / janfrog"
+!
+
+ivarName:something
+    ivarName := something.
+
+    "Created: / 12-04-2007 / 11:29:28 / janfrog"
+!
+
+label
+    | label start stop optionalSelector |
+
+    astNode isNil ifTrue:[ ^ 'No AST' ].
+
+    start := astNode startPosition.
+    stop := astNode endPosition.
+
+    astNode isMessage ifTrue:[
+        optionalSelector := ' #',astNode selector allBold.
+    ] ifFalse:[
+        optionalSelector := ''
+    ].
+    label := '%1 {%2%5} [%3..%4]' 
+                bindWith: self ivarName
+                    with: self astNodeName
+                    with: start ? '?'
+                    with: stop ? '?'
+                    with: optionalSelector.
+
+    (start isNil or:[ stop isNil ]) ifTrue:[ 
+        label := label asText colorizeAllWith: Color red.
+    ].
+    ^ label
+
+    "Created: / 28-03-2007 / 15:53:18 / janfrog"
+    "Modified: / 12-04-2007 / 11:30:23 / janfrog"
+    "Modified: / 07-08-2014 / 10:20:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+leafNodeAt: pos
+    | start stop |
+
+    start := astNode startPosition.
+    stop := astNode endPosition.
+    self children do:[:each | 
+        | leaf |
+        leaf := each leafNodeAt: pos.            
+        leaf notNil ifTrue:[ ^ leaf ].
+    ].
+    (start notNil and:[stop notNil]) ifTrue:[
+        (pos between: start and: stop) ifTrue:[ ^ self ].
+    ].
+    ^ nil.
+
+    "Created: / 10-04-2014 / 08:02:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+node
+    ^ astNode
+
+    "Created: / 28-03-2007 / 15:51:49 / janfrog"
+    "Created: / 26-11-2011 / 11:48:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/smallsense/SmallSense__ParseTreeInspector.st,v 1.2 2015-02-04 09:46:31 cg Exp $'
+!
+
+version_CVS
+    ^ '$Path: stx/goodies/smallsense/SmallSense__ParseTreeInspector.st, Version: 1.0, User: cg, Time: 2015-02-04T10:46:56.332+01$'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id: SmallSense__ParseTreeInspector.st,v 1.2 2015-02-04 09:46:31 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__PluggablePO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,121 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#PluggablePO
+	instanceVariableNames:'icon hint subject'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!PluggablePO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!PluggablePO methodsFor:'accessing'!
+
+hint
+    "Return a hint text to be displayed in gray after a label
+     (if there's space). If nil is returned, no hint is shown"
+
+    ^ hint
+
+    "Created: / 13-12-2014 / 07:51:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hint:something
+    hint := something.
+!
+
+icon
+    ^ icon
+!
+
+icon:something
+    icon := something.
+!
+
+label
+    "Return a text to be displayed. The label may be cached
+     `label` instvar."
+
+    ^ label
+
+    "Created: / 13-12-2014 / 07:49:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label: aString
+    label := aString
+
+    "Created: / 13-12-2014 / 12:25:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage:aProgrammingLanguage
+    "Answers a string to complete"
+
+    ^ self shouldNotImplement
+
+    "Created: / 13-12-2014 / 07:50:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+subject:something
+    subject := something.
+! !
+
+!PluggablePO methodsFor:'accessing-private'!
+
+subject
+    "Return the real object for which the receiver
+     is a presentor.
+     
+     For internal usage only."
+
+    ^ subject
+
+    "Created: / 13-12-2014 / 07:50:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PluggablePO methodsFor:'testing'!
+
+isSmallSensePluggablePO
+    ^ true
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__PluggableSearchProcessor.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,110 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSearchProcessor subclass:#PluggableSearchProcessor
+	instanceVariableNames:'label search presentation'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!PluggableSearchProcessor class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!PluggableSearchProcessor class methodsFor:'instance creation'!
+
+search: searchBlock presentation: presentBlock
+    ^ self new initializeWithSearch: searchBlock presentation: presentBlock
+
+    "Created: / 24-01-2015 / 00:14:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PluggableSearchProcessor methodsFor:'accessing'!
+
+label:something
+    label := something.
+! !
+
+!PluggableSearchProcessor methodsFor:'accessing - presentation'!
+
+label
+    "Return a label for this processor. This one is used as section label
+     in Spotter"
+
+    ^ label
+
+    "Created: / 24-01-2015 / 00:09:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PluggableSearchProcessor methodsFor:'initialization'!
+
+initializeWithSearch: searchBlock presentation: presentBlock
+    search := searchBlock.
+    presentation := presentBlock
+
+    "Created: / 24-01-2015 / 00:15:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PluggableSearchProcessor methodsFor:'searching'!
+
+matchingObjectPOsFor:objects
+    "superclass SmallSense::AbstractSearchProcessor says that I am responsible to implement this method"
+
+    | pos |
+
+    pos := objects collect: presentation.
+    pos isSequenceable ifFalse:[ 
+        pos := pos asArray.
+    ].
+    ^ pos sort:[ :a :b | a label == b label ]
+
+    "Created: / 24-01-2015 / 00:17:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchingObjectsForPattern:pattern filter:filter inEnvironment:environment relax:level
+    "superclass SmallSense::AbstractSearchProcessor says that I am responsible to implement this method"
+
+    ^ search value: pattern value: filter value: environment value: level
+
+    "Created: / 24-01-2015 / 00:16:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ProtocolSelectDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,115 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSelectDialog subclass:#ProtocolSelectDialog
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-Search'
+!
+
+!ProtocolSelectDialog class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!ProtocolSelectDialog methodsFor:'accessing - private'!
+
+matchingObjectForString: aString
+    "Creates a new object from given string. Called only when
+     #canCreateMatchingObjectFromString: returns true"
+
+    ^ aString asSymbol
+
+    "Created: / 23-06-2014 / 15:25:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ProtocolSelectDialog methodsFor:'accessing-defaults'!
+
+defaultTitle
+    ^ (resources string: 'Select Protocol...')
+
+    "Created: / 13-12-2014 / 12:57:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ProtocolSelectDialog methodsFor:'queries'!
+
+canCreateMatchingObjectFromString:string 
+    "Return true, a new object can be created with given string value"
+    
+    ^ string notEmptyOrNil
+
+    "Created: / 23-06-2014 / 15:15:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-01-2015 / 13:36:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+canSelect:selection
+    ^ selection isKindOf: PO
+
+    "Created: / 05-05-2014 / 23:50:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-12-2014 / 12:08:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ProtocolSelectDialog methodsFor:'searching'!
+
+matchingObjectPOsForPattern:pattern relax: level
+    | environment protocols |
+
+    environment := self environment.
+    protocols := Set new.
+
+    environment allMethodsDo:[ :mth | 
+        | protocol |
+
+        protocol := mth category.
+        (protocol notNil 
+            and: [ (filter isNil or:[filter value: protocol]) 
+            and: [ pattern isNil or:[pattern match: protocol relax: level] ] ]) ifTrue:[
+                protocols add: mth category 
+            ] 
+    ].
+    protocols := protocols asArray.
+    protocols sort: [ :a :b | a < b ].
+    ^ protocols collect:[ :e | PluggablePO new label: e; subject: e ].
+
+    "Created: / 13-12-2014 / 08:42:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-12-2014 / 12:55:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__RecognizerTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,810 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+TestCase subclass:#RecognizerTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests-Obsolete'
+!
+
+!RecognizerTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!RecognizerTests methodsFor:'RecognizerTest'!
+
+testRecognizer1
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| ahoj|        
+
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:2
+                position:2
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size > 17).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 04-03-2011 / 12:55:37 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 18:45:41 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer10
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    c
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:7
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size > 18).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:27:26 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 18:49:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer11
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    c fl
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:7
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size > 18).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:34:06 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 18:50:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer12
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    c fl:[
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:12
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size > 48).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:39:40 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:04:40 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer13
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    c fl:[# >
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:14
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size > 48).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:40:28 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:04:55 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer14
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    c fl:[# >  he
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:18
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size = 3).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:43:01 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:05:34 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer15
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    c fl:[# >  he   ah
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:23
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size > 48).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:55:35 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:05:44 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer16
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+self
+
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:2
+                position:6
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size >= self class selectors size).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 04-04-2011 / 14:05:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:05:56 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer2
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| ahoj|
+    u
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:7
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size > 92).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 04-03-2011 / 16:23:04 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 18:46:09 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer3
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    helper
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:12
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size =1).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 04-03-2011 / 17:40:05 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 18:47:48 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer4
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    10
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:8
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size >= 142).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 18:14:26 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 18:41:05 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer5
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    self
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:10
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size >= self class selectors size).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 18:33:31 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 04-04-2011 / 14:06:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:06:08 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer6
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    super
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:11
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size >= 503).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 18:35:35 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 08-04-2011 / 00:06:23 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer7
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    :
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:11
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size >17).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 18:39:58 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 18:45:29 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer8
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    :
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:6
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size >= 48).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:26:53 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:07:02 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testRecognizer9
+    |collector recognizer foundCollection|
+
+    collector := self 
+                doForSource:'
+| helper|
+    :
+                    u := 3.
+                    b:=u.
+                    c:=  u  floor  aa   .
+                    d  floor: u.
+                    d floor: 3 b:u.
+                    self rememberSymbolUsed:nil  . c  call: b  . b call:c dd:d.
+                    array := #(3 4  5 6 ).
+                    val := ConstantNode type:tokenType 
+                                        value:tokenValue.
+                    [ u== #Symbol  or: [u=3  ]  ]  ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ]   
+                    ^self.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    recognizer := SmallSenseRecognizer new.
+    foundCollection := recognizer 
+                recognize:3
+                position:4
+                collector:collector.
+    self assert:(foundCollection ~~ OrderedCollection).
+    self assert:(foundCollection objectNameCollection size >= 48).
+
+    "    self assert:(foundNode beforeNode).
+        self assert:((foundNode line)=2).
+        self assert:((foundNode position)=2).
+        self assert:(foundNode statement isErrorNode).
+        self assert:(foundNode statement errorToken =':=').
+        self assert:(foundNode beforeStatement isNil)."
+
+    "Created: / 07-03-2011 / 19:27:11 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 06-04-2011 / 19:07:13 / Jakub <zelenja7@fel.cvut.cz>"
+! !
+
+!RecognizerTests class methodsFor:'documentation'!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SelectorNode.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,127 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+ParseNode subclass:#SelectorNode
+	instanceVariableNames:'value'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk'
+!
+
+!SelectorNode class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    A (helper) node that represents a selector (or its part).
+    SelectorNodes are not directly created nor used by the
+    parser/compiler itself.
+
+    Some custom subclasses (syntax highlighters for instance)
+    makes use of it.
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+        SyntaxHighlighter2
+
+"
+! !
+
+!SelectorNode class methodsFor:'instance creation'!
+
+value: selector from: start to: end
+
+    ^self new
+        value: selector;
+        startPosition:start endPosition: end
+
+    "Created: / 16-02-2012 / 20:56:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SelectorNode methodsFor:'accessing'!
+
+value
+    ^ value
+!
+
+value:aString
+    value := aString.
+! !
+
+!SelectorNode methodsFor:'navigation-SmallSense'!
+
+navigateToUsing: navigator
+    | p |
+
+    p := self parent.
+    p notNil ifTrue:[
+        p navigateToUsing: navigator
+    ] ifFalse:[ 
+        self breakPoint: #jv  
+    ].
+
+    "Created: / 24-09-2013 / 10:04:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-11-2014 / 15:47:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SelectorNode methodsFor:'testing'!
+
+isSelector
+
+    ^true
+
+    "Created: / 16-02-2012 / 21:04:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SelectorNode class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SettingsAppl.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,492 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+AbstractSettingsApplication subclass:#SettingsAppl
+	instanceVariableNames:'smallSenseEnabled smallSenseEnabledAndMethodsSwizzledHolder
+		smallSenseBackgroundTypingEnabled smallSenseBackgroundLintEnabled
+		smallSenseElectricEditSupportEnabled
+		smallSenseCompleteIfUnambiguous smallSenseCompletionEnabled
+		smallSenseSwizzledInfoHolder smallSenseNewDialogsEnabled'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface'
+!
+
+!SettingsAppl class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SettingsAppl class methodsFor:'class initialization'!
+
+initialize
+
+    NewLauncher
+        addSettingsApplicationByClass: self name
+        withName: 'Tools/SmallSense'
+        icon: nil.
+
+    "Created: / 04-02-2012 / 21:50:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2014 / 14:23:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SettingsAppl class methodsFor:'help specs'!
+
+helpSpec
+    "This resource specification was automatically generated
+     by the UIHelpTool of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIHelpTool may not be able to read the specification."
+
+    "
+     UIHelpTool openOnClass:SmallSense::SettingsAppl
+    "
+
+    <resource: #help>
+
+    ^ super helpSpec addPairsFrom:#(
+
+#smallSenseBackgroundLintEnabled
+'When enabled, a hint on code are shown next to the line number,\based on a static code analysis (SmallLint).\See the SmallLint settings for which rules are to be applied'
+
+#smallSenseBackgroundTypingEnabled
+'When enabled, SmallSense runs a type-inferencer on the code to give more accurate type hints and completion data'
+
+#smallSenseCompleteIfUnambiguous
+'Enable automatic completion if unambigious.\Will automatically insert the completion, if there only one possible completion is found.\This may be somewhat disturbing, as it makes blind typing a little tricky.'
+
+#smallSenseCompletionEnabled
+'Enable the SmallSense completion algorithm, instead of the default one.\It is currently a matter of personal taste, which one provides better completions'
+
+#smallSenseElectricEditSupportEnabled
+'When enabled, closing brackets, blank lines and spaces are automatically inserted,\as soon as opening bracket or other tokens are typed. Honours formatting settings.'
+
+#smallSenseEnabled
+'General enable/disable the SmallSense support package'
+
+#smallSenseNewDialogsEnabled
+'EXPERIMENTAL. When enabled, use SmallSense''s own dialogs for classes, methods, packages, ...\Requires swizzling.'
+
+)
+! !
+
+!SettingsAppl class methodsFor:'interface specs'!
+
+windowSpec
+    "This resource specification was automatically generated
+     by the UIPainter of ST/X."
+
+    "Do not manually edit this!! If it is corrupted,
+     the UIPainter may not be able to read the specification."
+
+    "
+     UIPainter new openOnClass:SmallSense::SettingsAppl andSelector:#windowSpec
+     SmallSense::SettingsAppl new openInterface:#windowSpec
+     SmallSense::SettingsAppl open
+    "
+
+    <resource: #canvas>
+
+    ^
+    #(FullSpec
+       name: windowSpec
+       window:
+      (WindowSpec
+         label: 'SmallSense Settings'
+         name: 'SmallSense Settings'
+         min: (Point 10 10)
+         bounds: (Rectangle 0 0 536 651)
+       )
+       component:
+      (SpecCollection
+         collection: (
+          (CheckBoxSpec
+             label: 'Enable SmallSense '
+             name: 'Enable'
+             layout: (LayoutFrame 0 0 0 0 0 1 30 0)
+             activeHelpKey: smallSenseEnabled
+             model: smallSenseEnabled
+             translateLabel: true
+           )
+          (LabelSpec
+             label: 'Methods not swizzled, some features may not be available'
+             name: 'SwizzlingInfo'
+             layout: (LayoutFrame 23 0 30 0 0 1 55 0)
+             visibilityChannel: hasMethodsToSwizzle
+             translateLabel: true
+             labelChannel: smallSenseSwizzledInfoHolder
+             adjust: left
+           )
+          (LinkButtonSpec
+             label: 'What''s this?'
+             name: 'Button1'
+             layout: (LayoutFrame -100 1 30 0 0 1 55 0)
+             visibilityChannel: hasMethodsToSwizzle
+             foregroundColor: (Color 0.0 0.0 100.0)
+             translateLabel: true
+             model: smallSenseSwizzlingDocumentationOpen
+           )
+          (DividerSpec
+             name: 'Separator'
+             layout: (LayoutFrame 5 0 56 0 -5 1 60 0)
+           )
+          (VerticalPanelViewSpec
+             name: 'Panel'
+             layout: (LayoutFrame 5 0 61 0 -5 1 26 1)
+             horizontalLayout: fit
+             verticalLayout: top
+             horizontalSpace: 3
+             verticalSpace: 3
+             component:
+            (SpecCollection
+               collection: (
+                (ViewSpec
+                   name: 'Spacer1'
+                   extent: (Point 526 15)
+                 )
+                (LabelSpec
+                   label: 'Code Editor'
+                   name: 'Label1'
+                   translateLabel: true
+                   adjust: left
+                   extent: (Point 526 22)
+                 )
+                (CheckBoxSpec
+                   label: 'Enable Code Analysis (Lint)'
+                   name: 'LintEnabled'
+                   activeHelpKey: smallSenseBackgroundLintEnabled
+                   enableChannel: smallSenseEnabled
+                   model: smallSenseBackgroundLintEnabled
+                   translateLabel: true
+                   extent: (Point 526 22)
+                 )
+                (CheckBoxSpec
+                   label: 'Enable Background Type Inferencer'
+                   name: 'CheckBox2'
+                   activeHelpKey: smallSenseBackgroundTypingEnabled
+                   enableChannel: smallSenseEnabledAndMethodsSwizzledHolder
+                   model: smallSenseBackgroundTypingEnabled
+                   translateLabel: true
+                   extent: (Point 526 22)
+                 )
+                (CheckBoxSpec
+                   label: 'Enable "Electric Edit" Support'
+                   name: 'CheckBox3'
+                   activeHelpKey: smallSenseElectricEditSupportEnabled
+                   enableChannel: smallSenseEnabled
+                   model: smallSenseElectricEditSupportEnabled
+                   translateLabel: true
+                   extent: (Point 526 22)
+                 )
+                (CheckBoxSpec
+                   label: 'Enable Code Completion (using SmallSense Completion Engine)'
+                   name: 'CheckBox4'
+                   activeHelpKey: smallSenseCompletionEnabled
+                   enableChannel: smallSenseEnabled
+                   model: smallSenseCompletionEnabled
+                   translateLabel: true
+                   extent: (Point 526 22)
+                 )
+                (CheckBoxSpec
+                   label: 'Auto-complete when Completion is Unambiguous'
+                   name: 'CheckBox5'
+                   activeHelpKey: smallSenseCompleteIfUnambiguous
+                   enableChannel: smallSenseEnabledAndCompletionEnabled
+                   model: smallSenseCompleteIfUnambiguous
+                   translateLabel: true
+                   extent: (Point 526 22)
+                 )
+                (ViewSpec
+                   name: 'Spacer2'
+                   extent: (Point 526 15)
+                 )
+                (LabelSpec
+                   label: 'Dialogs'
+                   name: 'Label2'
+                   translateLabel: true
+                   adjust: left
+                   extent: (Point 526 22)
+                 )
+                (CheckBoxSpec
+                   label: 'Enable New Dialogs (EXPERIMENTAL)'
+                   name: 'CheckBox6'
+                   activeHelpKey: smallSenseNewDialogsEnabled
+                   enableChannel: smallSenseEnabledAndMethodsSwizzledHolder
+                   model: smallSenseNewDialogsEnabled
+                   translateLabel: true
+                   extent: (Point 526 28)
+                 )
+                )
+
+             )
+           )
+          )
+
+       )
+     )
+
+! !
+
+!SettingsAppl methodsFor:'actions'!
+
+smallSenseSwizzlingDocumentationOpen
+    <resource: #uiCallback>
+
+   OperatingSystem openApplicationForDocument: 'https://bitbucket.org/janvrany/stx-goodies-smallsense/wiki/Swizzling.md'  operation: #open
+
+    "Modified: / 13-01-2015 / 09:28:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SettingsAppl methodsFor:'aspects'!
+
+smallSenseBackgroundLintEnabled
+
+
+    smallSenseBackgroundLintEnabled isNil ifTrue:[
+        smallSenseBackgroundLintEnabled := true asValue.
+        smallSenseBackgroundLintEnabled onChangeSend:#updateModifiedChannel to:self.
+    ].
+    ^ smallSenseBackgroundLintEnabled.
+
+    "Modified: / 04-02-2012 / 21:47:56 / Jan Vrany "
+!
+
+smallSenseBackgroundTypingEnabled
+
+
+    smallSenseBackgroundTypingEnabled isNil ifTrue:[
+        smallSenseBackgroundTypingEnabled := true asValue.
+        smallSenseBackgroundTypingEnabled onChangeSend:#updateModifiedChannel to:self.
+    ].
+    ^ smallSenseBackgroundTypingEnabled.
+
+    "Modified: / 04-02-2012 / 21:48:02 / Jan Vrany "
+!
+
+smallSenseCompleteIfUnambiguous
+
+
+    smallSenseCompleteIfUnambiguous isNil ifTrue:[
+        smallSenseCompleteIfUnambiguous := true asValue.
+        smallSenseCompleteIfUnambiguous onChangeSend:#updateModifiedChannel to:self.
+    ].
+    ^ smallSenseCompleteIfUnambiguous.
+
+    "Created: / 18-01-2014 / 23:36:58 / Jan Vrany "
+!
+
+smallSenseCompletionEnabled
+
+
+    smallSenseCompletionEnabled isNil ifTrue:[
+        smallSenseCompletionEnabled := true asValue.
+        smallSenseCompletionEnabled onChangeSend:#updateModifiedChannel to:self.
+    ].
+    ^ smallSenseCompletionEnabled.
+
+    "Modified: / 27-02-2014 / 09:33:53 / Jan Vrany "
+!
+
+smallSenseElectricEditSupportEnabled
+
+
+    smallSenseElectricEditSupportEnabled isNil ifTrue:[
+        smallSenseElectricEditSupportEnabled := true asValue.
+        smallSenseElectricEditSupportEnabled onChangeSend:#updateModifiedChannel to:self.
+    ].
+    ^ smallSenseElectricEditSupportEnabled.
+
+    "Modified: / 26-07-2013 / 12:36:25 / Jan Vrany "
+!
+
+smallSenseEnabled
+
+
+    smallSenseEnabled isNil ifTrue:[
+        smallSenseEnabled := true asValue.
+        smallSenseEnabled onChangeSend:#updateModifiedChannel to:self.
+    ].
+    ^ smallSenseEnabled.
+
+    "Modified: / 04-02-2012 / 21:48:11 / Jan Vrany "
+!
+
+smallSenseEnabledAndCompletionEnabled
+    ^ BlockValue forLogical: self smallSenseEnabled and: self smallSenseCompletionEnabled
+
+    "Created: / 27-02-2014 / 09:41:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+smallSenseEnabledAndMethodsSwizzledHolder
+    smallSenseEnabledAndMethodsSwizzledHolder isNil ifTrue:[
+        smallSenseEnabledAndMethodsSwizzledHolder :=
+            PluggableAdaptor on: self smallSenseEnabled getter:[ :model | model value and:[ self smallSenseSwizzled ] ]
+    ].
+    ^ smallSenseEnabledAndMethodsSwizzledHolder.
+
+    "Created: / 13-01-2015 / 09:44:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+smallSenseNewDialogsEnabled
+    <resource: #uiAspect>
+
+    "automatically generated by UIPainter ..."
+
+    "*** the code below creates a default model when invoked."
+    "*** (which may not be the one you wanted)"
+    "*** Please change as required and accept it in the browser."
+    "*** (and replace this comment by something more useful ;-)"
+
+    smallSenseNewDialogsEnabled isNil ifTrue:[
+        smallSenseNewDialogsEnabled := true asValue.
+"/ if your app needs to be notified of changes, uncomment one of the lines below:
+"/       smallSenseNewDialogsEnabled addDependent:self.
+"/       smallSenseNewDialogsEnabled onChangeSend:#smallSenseNewDialogsEnabledChanged to:self.
+        smallSenseNewDialogsEnabled onChangeSend:#updateModifiedChannel to:self.
+    ].
+    ^ smallSenseNewDialogsEnabled.
+
+    "Modified: / 10-05-2014 / 11:56:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+smallSenseSwizzled
+    ^ (Smalltalk at: #stx_goodies_smallsense) swizzled
+
+    "Created: / 12-01-2015 / 07:25:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+smallSenseSwizzledInfoHolder
+    smallSenseSwizzledInfoHolder isNil ifTrue:[
+        smallSenseSwizzledInfoHolder := ValueHolder new.
+        (Smalltalk at: #stx_goodies_smallsense) swizzled ifTrue:[
+            smallSenseSwizzledInfoHolder value:
+                ((resources string: 'Methods swizzled.') asText allBold colorizeAllWith: Color green darker).
+        ] ifFalse:[
+            smallSenseSwizzledInfoHolder value:
+                (resources string: 'Methods not swizzled, some features may not be available.')
+        ].
+    ].
+    ^ smallSenseSwizzledInfoHolder
+
+    "Created: / 12-01-2015 / 07:20:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SettingsAppl methodsFor:'protocol'!
+
+basicAspects
+    ^#(
+       smallSenseEnabled
+
+       smallSenseBackgroundLintEnabled
+       smallSenseBackgroundTypingEnabled
+       smallSenseElectricEditSupportEnabled
+
+       smallSenseCompletionEnabled
+       smallSenseCompleteIfUnambiguous
+
+       smallSenseNewDialogsEnabled
+    )
+
+    "Modified: / 10-05-2014 / 00:04:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+basicReadSettings
+    self readAspects:self basicAspects from:currentUserPrefs.
+
+    "Modified: / 19-07-2011 / 17:11:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+basicSaveSettings
+
+    self writeAspects:self basicAspects to:currentUserPrefs.
+
+    "Modified: / 26-07-2011 / 10:43:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+helpFilename
+    "subclasses must return the relative name of a helpFile
+     in the doc/online/<language>/help directory.
+     Or nil, if no help is available."
+
+    ^ self shouldImplement
+! !
+
+!SettingsAppl methodsFor:'queries'!
+
+hasMethodsToSwizzle
+    "Return true, if this SmallSense version has anything to swizzle"
+
+    ^ (Smalltalk at: #stx_goodies_smallsense) extensionMethods
+        anySatisfy: [ :m | (m annotationAt: #swizzle:) notNil or:[(m annotationAt: #swizzle:checksum:) notNil ] ]
+
+    "
+    SmallSense::SettingsAppl basicNew hasMethodsToSwizzle
+
+    (Smalltalk at: #stx_goodies_smallsense) extensionMethods
+        select: [ :m | (m annotationAt: #swizzle:) notNil or:[(m annotationAt: #swizzle:checksum:) notNil ] ]
+
+    "
+
+    "Created: / 13-01-2015 / 09:33:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hasUnsavedChanges
+    ^ self
+        hasChangedAspectIn: self basicAspects
+        asComparedTo:currentUserPrefs
+
+    "Modified: / 19-07-2011 / 17:12:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 25-11-2011 / 15:25:16 / cg"
+! !
+
+!SettingsAppl class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
+
+SettingsAppl initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkChecker.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,156 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SmalllintChecker subclass:#SmalltalkChecker
+	instanceVariableNames:''
+	classVariableNames:'Errors'
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Lint'
+!
+
+!SmalltalkChecker class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    SmallSenseChecker is customized SmalllintChecker used
+    by SmallSense's checking services. Do not use it in your
+    code, use SmalllintChecker instead.
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+        SmalllintChecker
+        SmallSenseService
+
+"
+! !
+
+!SmalltalkChecker class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    Errors := Dictionary new.
+
+    "Modified: / 06-09-2012 / 14:18:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkChecker class methodsFor:'accessing'!
+
+forceDisabledRules
+    "Return a list of rule class names that
+     are never run by SmallSense's checker - they
+     are either buggy (i.e.. not ready to be run
+     incrementally) or it does not make sense to run them
+     Add with care!!!!!!
+    "
+
+    ^ #(
+        RBLawOfDemeterRule          "/ Too many false positives, hard to fix
+        RBImplementedNotSentRule    "/ Uses Context>>#computeLiterals whichs toooo slow.
+        RBSentNotImplementedRule    "/ Uses Context>>#computeLiterals whichs toooo slow.
+        RBUndeclaredReferenceRule   "/
+
+        RBNilOrEmptyCollectionReplaceRule   "/ only for Squeak - I don't want people to rewrite ST/X code
+        RBSTXSpecialCommentsRule            "/ a rewriter to be used only for porting
+    )
+
+    "Created: / 17-02-2012 / 13:10:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 30-09-2014 / 11:59:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkChecker methodsFor:'private'!
+
+checkClass: aClass 
+
+    "Nothing to do, SmallSense checker checks only methods"
+    context selectedClass: aClass.
+
+    "Created: / 16-02-2012 / 16:12:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+checkMethodsForClass: aClass
+
+    environment selectorsForClass: aClass do: [:sel|
+        context selector: sel.
+        context parseTree notNil ifTrue:[
+            rule flattened do:[:each|
+                [
+                    each checkMethod: context.
+                ] on: Error do:[:ex|
+                    SmalltalkLintService debugging ifTrue:[
+                        SmalltalkLintService debugging: false.
+                        ex pass.
+                    ] ifFalse:[
+                        Errors at: each class ifAbsentPut:[  (context selectedClass compiledMethodAt: context selector) source ].
+                    ]
+                ]
+            ].
+        ].
+    ]
+
+    "Modified: / 24-08-2010 / 21:32:39 / Jan Vrany <enter your email here>"
+    "Created: / 17-02-2012 / 00:50:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 16-10-2014 / 01:08:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkChecker class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
+
+SmalltalkChecker initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkCompletionEngine.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,581 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+CompletionEngine subclass:#SmalltalkCompletionEngine
+	instanceVariableNames:'collector'
+	classVariableNames:'Debug'
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk'
+!
+
+!SmalltalkCompletionEngine class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkCompletionEngine class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    Debug := false.
+
+    "Modified: / 22-01-2014 / 09:08:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngine class methodsFor:'accessing'!
+
+debug
+    ^ Debug
+
+    "Created: / 22-01-2014 / 09:08:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+debug: aBoolean
+    Debug := aBoolean .
+    "
+    self debug: true.
+    self debug: false.
+    "
+
+    "Created: / 22-01-2014 / 09:08:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 22-01-2014 / 19:42:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngine class methodsFor:'utilities'!
+
+resultSetFor: mode source: source class: class line: line column: col
+    | inferencer tree |
+
+    mode == #method ifTrue:[
+        inferencer := SmalltalkInferencer forClass: class methodSource: source asString.
+        inferencer parserClass: SmalltalkParser.
+        inferencer process.
+    ] ifFalse:[
+        self breakPoint: #jv.
+        ^nil.
+        inferencer := Parser for: (source asString readStream).
+        "JV@2011-06-13: HACK, use polymorphism"
+        tree := inferencer
+            parseExpressionWithSelf:nil
+            notifying:nil
+            ignoreErrors:false
+            ignoreWarnings:false
+            inNameSpace:nil.
+        inferencer tree: tree.
+    ].
+    ^ self new
+        completeAtLine:line
+        column:col
+        collector:inferencer
+
+    "Modified: / 07-04-2011 / 22:55:58 / Jakub <zelenja7@fel.cvut.cz>"
+    "Created: / 26-11-2011 / 17:53:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-09-2013 / 14:43:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 02-10-2013 / 13:09:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngine methodsFor:'completion-helpers'!
+
+javaClassesDo: aBlock
+    | class loader loaders |
+
+    class := collector klass.
+    loaders := Set new.
+    loader := (class notNil and:[class isJavaClass]) ifTrue:[class classLoader] ifFalse:[JavaVM systemClassLoader].
+    [ loader notNil ] whileTrue:[
+        loaders add: loader.
+        loader := loader instVarNamed: #parent.
+    ].
+    loaders add: nil.
+
+    JavaVM registry  allClassesDo:[:cls|
+        (cls isAnonymous not and:[(loaders includes: cls classLoader)]) ifTrue:[
+
+            aBlock value: cls.
+        ].
+    ].
+
+    "Created: / 04-10-2013 / 13:10:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 13:03:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngine methodsFor:'completion-individual'!
+
+addClassVariables
+    | class |
+
+    class := collector klass theNonMetaclass.
+    class classVarNames do:[:nm|
+        result add:(VariablePO classVariable: nm in: class).
+    ].
+
+    "Created: / 24-07-2013 / 17:00:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 30-07-2013 / 23:32:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addGlobalsStartingWith: prefix
+
+    | class namespace environment |
+    class := collector klass.
+    namespace := class nameSpace.
+    environment := context environment.
+    "nameSpace may return private class, sigh"
+    [ namespace isNameSpace ] whileFalse:[ namespace := namespace nameSpace ].
+
+    environment keysDo:[:name |
+            | value |
+
+            (self isGlobalKeyForClassVariable: name) ifFalse:[ 
+                value := environment at: name.
+                ((name startsWith: prefix) or:[(value isBehavior and:[(value nameWithoutPrefix startsWith: prefix) or:[value nameWithoutNameSpacePrefix startsWith: prefix]])]) ifTrue:[
+                    (value notNil and:[value isBehavior]) ifTrue:[ 
+                        "/ Check for aliases...
+                        | clsnm |
+
+                        clsnm := value name.
+                        clsnm = name ifTrue:[ 
+                            result add: (PO forClass: value)
+                        ] ifFalse:[ 
+                            result add: (PO forGlobalNamed: name)  
+                        ].
+                    ] ifFalse:[ 
+                        result add: (PO forGlobalNamed: name)  
+                    ].
+                ]
+            ].
+        ].
+
+    "Created: / 26-11-2011 / 17:29:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-07-2014 / 17:51:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addJavaClassesInPackage: prefix
+    prefix isEmptyOrNil ifTrue:[
+        self javaClassesDo: [:cls |
+            result add: (ClassPO new klass: cls; showPrefix: true; yourself)
+        ].
+    ] ifFalse:[
+        self javaClassesDo: [:cls |
+            (cls binaryName startsWith: prefix) ifTrue:[
+                result add: (ClassPO new klass: cls; showPrefix: true; yourself)
+            ].
+        ].
+
+    ].
+
+    "Created: / 04-10-2013 / 13:09:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-10-2013 / 02:42:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsForType: type
+    ^ self addMethodsForType: type stripOff: nil
+
+    "Created: / 26-11-2011 / 17:03:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-05-2014 / 12:51:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsForType: type prefix: prefix stripOff: stripprefix
+
+    type isUnknownType ifFalse:[
+        self addMethodsForType:type stripOff: stripprefix.
+
+        "/ If the type is union of more than 6 types, then
+        "/ assume that the inferencer is likely wrong.
+        "/ then, if the prefix is at least 3 chars,
+        "/ also add methods with that prefix.
+
+        ((type classes size > 6) and:[ prefix size > 2 ]) ifTrue:[
+            self addMethodsStartingWith:prefix stripOff: stripprefix
+        ].
+    ] ifTrue:[
+        self addMethodsStartingWith:prefix stripOff: stripprefix
+    ].
+
+    "Created: / 08-04-2014 / 21:04:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-04-2014 / 09:31:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addMethodsForType: type stripOff: stripprefix
+    | classes seen selector2classesMap |
+
+    selector2classesMap := Dictionary new.
+    classes := type classes.
+    "/ Hack for Boolean: ifTrue:iFalse: etc are not defined
+    "/ in Boolean ?!!?
+    (classes size == 1 and:[classes anElement == Boolean ]) ifTrue:[
+        classes := Array with: True with: False.
+    ].
+    classes size == 1 ifTrue:[
+        classes anElement == JavaPackage class ifTrue:[
+            "/ Special hack for JAVA: for pattern `JAVA java lang reflect`
+            "/ complete all Java classes in that package
+            | node |
+
+            node := result context node.
+            node isUnaryMessage ifTrue:[
+                | package |
+                "/ Compute package prefix...
+
+                package := node selector.
+                node := node receiver.
+                [ node isUnaryMessage ] whileTrue:[
+                    package := node selector , '/' , package.
+                    node := node receiver.
+                ].
+                self addJavaClassesInPackage: package.
+                ^ self.
+            ]
+        ]
+    ].
+
+    seen := Set new.
+    classes do: [:each |
+        | class selector2classMap |
+
+        class := each.
+        selector2classMap := Dictionary new.
+
+        "/ Now, special care for Java classes, sigh...
+        (class isMetaclass and:[class theNonMetaclass isJavaClass]) ifTrue:[
+            seen add: class.
+            class theNonMetaclass selectorsAndMethodsDo: [:selector :met |
+                met isStatic ifTrue:[
+                    result add: (PO forClass: met mclass selector: selector)
+                ].
+            ].
+        ] ifFalse:[
+            [ class notNil and:[(seen includes: class) not]] whileTrue: [
+                class selectorsAndMethodsDo: [:selector :met |
+                    met isSynthetic ifFalse:[
+                        (stripprefix isNil or:[ selector size > stripprefix size and:[selector startsWith: stripprefix]]) ifTrue:[
+                            selector2classMap at: selector put: class.
+                        ].
+                    ]
+                ].
+                class := class superclass.
+            ]
+        ].
+        selector2classMap keysAndValuesDo:[:selector :class |
+            | classes |
+
+            classes := selector2classesMap at: selector ifAbsentPut: [ Set new ].
+            classes add: class.
+        ]
+    ].
+
+    selector2classesMap keysAndValuesDo: [:selector :classes|
+        result add:(MethodPO forClasses: classes selector: selector prefix: stripprefix)
+    ]
+
+    "Created: / 08-04-2014 / 21:23:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 10:47:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addPools
+    | class |
+
+    class := collector klass theNonMetaclass.
+    class theNonMetaclass sharedPools do:[:pool|
+        pool theNonMetaclass classVarNames do:[:nm|
+            result add:(VariablePO classVariable: nm in: pool).
+        ]
+    ].
+
+    "Created: / 24-07-2013 / 16:59:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 30-07-2013 / 23:32:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addVariablesFor: node
+
+    | n klass |
+
+    "Add Instance variables"
+    klass := collector klass.
+    [ klass notNil ] whileTrue:[
+        | usedInstVars |
+
+        usedInstVars := collector parser usedInstVars.
+        klass instVarNames do:[:nm |
+            | po |
+
+            po := VariablePO instanceVariable: nm in: klass.
+            "/ Raise relevance if the instvar is already used in the code...
+            (usedInstVars includes: nm) ifTrue:[
+                po relevance: (po relevance + 10).
+            ].
+
+            result add: po.
+        ].
+        "/ When on class side (i.e., in class method), do not complete
+        "/ instance variables of Class / ClassDescription / Behaviour
+        "/ as STC won't compile such code.
+        klass := (klass isMetaclass and:[klass superclass == Class])
+                    ifTrue:[nil]
+                    ifFalse:[klass superclass].
+    ].
+    "Add pseudo variables"
+    #(self super here thisContext) do:[:nm|
+        result add: (VariablePO new name: nm).
+    ].
+    "Add arguments"
+    collector parser methodArgs ? #() do:[:nm|
+        result add: (VariablePO argument: nm).
+    ].
+    "Add temporaries"
+    collector parser methodVars ? #() do:[:nm|
+        result add: (VariablePO variable: nm).
+    ].
+    "Add literals"
+    #(#true #false #nil ) do:[:nm|
+        result add: (SnippetPO new value: nm).
+    ].
+
+
+    n := node.
+    [ n notNil ] whileTrue:[
+        n isBlockNode ifTrue:[
+            n arguments ? #() do:[:barg|result add: (VariablePO variable: barg name)].
+            n variables ? #() do:[:bvar|result add: (VariablePO variable: bvar name)].
+        ].
+        n := n parent.
+    ]
+
+    "Created: / 31-07-2013 / 00:32:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 10:09:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngine methodsFor:'completion-private'!
+
+complete
+    "Compute completion for `codeView`, taking all the information
+     from it. Returns a CompletionResult with computed completions"
+
+    | class |
+
+    textView := context textView.
+    class := textView isCodeView2
+                ifTrue: [ textView klass ]
+                ifFalse: [ textView editedClass ].
+    class isNil ifTrue:[
+        class := UndefinedObject.
+    ].
+    ^ self complete: textView codeAspect source: textView contents string class: class line: textView cursorLine column: textView cursorCol
+
+    "Created: / 02-10-2013 / 13:32:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:53:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+complete: mode source: source class: class line: lineNrArg column: colNrArg
+    | inferencer lineNr colNr |
+
+    mode == #method ifTrue:[
+        lineNr := lineNrArg.
+        colNr := colNrArg.
+        inferencer := SmalltalkInferencer forClass: class methodSource: source asString.
+    ] ifFalse:[
+        | line |
+
+        lineNr := 1.
+        colNr := colNrArg.
+        line := textView list at: lineNrArg ifAbsent:[ nil ].
+        line isEmptyOrNil ifTrue:[ ^ nil ].
+        inferencer := SmalltalkInferencer forExpression: line.
+    ].
+    inferencer parserClass: SmalltalkParser.
+    inferencer process.
+
+    ^ self
+        completeAtLine:lineNr
+        column:colNr
+        collector:inferencer
+
+    "Created: / 02-10-2013 / 13:23:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-10-2013 / 13:43:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeAfter:node
+    "return collection of completion items after given node"
+
+    | type |
+
+    type := node inferedType.
+    type isUnknownType ifFalse:[
+        self addMethodsForType: node inferedType
+    ].
+
+    "Created: / 04-03-2011 / 15:45:28 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 08-04-2011 / 10:55:09 / Jakub <zelenja7@fel.cvut.cz>"
+    "Created: / 26-11-2011 / 17:07:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-09-2013 / 02:15:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeAtLine:line column:col collector:coll
+    "find most possible codeCompletion object"
+
+    | nodeToPosition |
+
+    collector := coll.
+    (collector tree isNil or:[collector tree == #Error]) ifTrue:[
+        ^ nil
+    ].
+    nodeToPosition := SmalltalkParseNodeFinder new
+                        findNodeIn: collector source tree: collector tree comments: collector parser commentPositions
+                        line: line column: col.
+    context node: nodeToPosition key position: nodeToPosition value.
+
+    context isAfterNode ifTrue:[
+        self completeAfter:context node.
+    ] ifFalse:[
+    context isInNode ifTrue:[
+        self completeIn:context node.
+    ] ifFalse:[
+    context isBeforeNode ifTrue:[
+        self completeBefore:context node.
+    ]]].
+
+    result isEmpty ifTrue:[
+        nil "/Only to set breakpoint here
+    ].
+    ^result.
+
+    "Created: / 04-03-2011 / 13:01:14 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 08-04-2011 / 10:52:59 / Jakub <zelenja7@fel.cvut.cz>"
+    "Created: / 26-11-2011 / 17:05:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-01-2014 / 10:36:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeBefore:node
+
+    self breakPoint: #jv. "Not yet implemented"
+
+    "Created: / 04-03-2011 / 15:45:28 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 08-04-2011 / 10:55:09 / Jakub <zelenja7@fel.cvut.cz>"
+    "Created: / 26-11-2011 / 17:07:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeIn:node
+    "return collection which can be afterNode"
+
+    node isVariableNode ifTrue:[
+        self completeInVariableNode:node.
+        ^ self.
+    ].
+    node isMessage ifTrue:[
+        self completeInMessageNode:node.
+        ^ self
+    ].
+    self breakPoint:#jv.
+
+    "Created: / 07-03-2011 / 18:59:02 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 08-04-2011 / 09:31:51 / Jakub <zelenja7@fel.cvut.cz>"
+    "Created: / 26-11-2011 / 17:07:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-04-2014 / 20:52:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeInMessageNode:node
+    | parent |
+
+
+    self addMethodsForType: node receiver inferedType prefix: node selector stripOff: nil.
+    parent := node parent.
+    parent isMessage ifTrue:[
+        self addMethodsForType: parent receiver inferedType prefix: node selector stripOff: parent selector.
+    ].
+
+    "Modified (format): / 08-04-2014 / 21:16:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completeInVariableNode:node
+    node name first isUppercase ifTrue:[
+        self addGlobalsStartingWith:node name.
+        self addClassVariables.
+        self addPools.
+    ] ifFalse:[
+        self addVariablesFor:node
+    ]
+
+    "Modified: / 24-07-2014 / 19:11:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngine methodsFor:'queries'!
+
+isGlobalKeyForClassVariable: aString
+    | i |
+
+    i := 0.
+    [
+        i := aString indexOf: $: startingAt: i + 1.
+        i ~~ 0
+    ] whileTrue:[
+        aString size > i ifTrue:[
+            (aString at: i + 1) ~~ $: ifTrue:[
+                ^ true
+            ].
+        ].
+        i := i + 1.
+    ].
+    ^ false
+
+    "
+    SmalltalkCompletionEngine new isGlobalKeyForClassVariable: 'AAA'
+    SmalltalkCompletionEngine new isGlobalKeyForClassVariable: 'AAA:X'
+    SmalltalkCompletionEngine new isGlobalKeyForClassVariable: 'BB::CC::AA'
+    SmalltalkCompletionEngine new isGlobalKeyForClassVariable: 'BB::CC::AA:X'
+    "
+
+    "Created: / 09-04-2014 / 13:49:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngine class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
+
+SmalltalkCompletionEngine initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkCompletionEngineTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,206 @@
+"{ Encoding: utf8 }"
+
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+CompletionEngineTests subclass:#SmalltalkCompletionEngineTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!SmalltalkCompletionEngineTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkCompletionEngineTests methodsFor:'accessing-classes'!
+
+completionEngineClass
+    "superclass SmallSense::CompletionEngineTests says that I am responsible to implement this method"
+
+    ^ SmalltalkCompletionEngine
+
+    "Created: / 24-07-2014 / 11:51:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+completionLanguage
+    ^ SmalltalkLanguage instance
+
+    "Created: / 07-03-2015 / 10:35:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngineTests methodsFor:'tests - classes'!
+
+test_classes_01a
+
+    codeView classHolder value: self class.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ SmalltalkCompletionEngineTe┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseClassPO and:[each klass == SmalltalkCompletionEngineTests]]) size == 1.
+
+    "Created: / 24-07-2014 / 15:12:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:08:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_classes_01b
+
+    codeView classHolder value: self class.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ OrderedColl┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseClassPO and:[each klass == OrderedCollection]]) size == 1.
+
+    "Created: / 24-07-2014 / 15:12:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:10:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_classes_01c
+
+    codeView classHolder value: self class.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ OperatingSyst┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseVariablePO and:[each name = 'OperatingSystem' ]]) size == 1.
+
+    "Created: / 24-07-2014 / 15:14:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:10:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_classes_02a
+
+    codeView classHolder value: self class.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ Phase┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseClassPO and:[each klass = SmalltalkInferencer::Phase1 ]]) size == 1.
+
+    "Created: / 24-07-2014 / 17:50:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:10:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_classes_02b
+
+    codeView classHolder value: self class.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ SmalltalkInfe┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseClassPO and:[each klass = SmalltalkInferencer::Phase1 ]]) size == 1.
+
+    "Created: / 24-07-2014 / 17:50:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:10:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_classes_03
+
+    codeView classHolder value: self class.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ ClassL┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseClassPO and:[each klass = Tools::ClassList ]]) size == 1.
+
+    "Created: / 24-07-2014 / 17:53:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:10:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_classes_04
+
+    codeView classHolder value: SmalltalkInferencer.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ Pha┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseClassPO and:[each klass = SmalltalkInferencer::Phase1 ]]) size == 1.
+    self assert: (result select:[:each | each isSmallSenseClassPO and:[each klass = SmalltalkInferencer::Phase2 ]]) size == 1.
+
+    "Created: / 24-07-2014 / 19:10:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:11:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_classes_05
+
+    codeView classHolder value: SmalltalkInferencer.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ Scree┃'.
+
+    self assert: result notEmpty.
+    self assert: (result select:[:each | each isSmallSenseVariablePO and:[each name = 'Screen' ]]) size == 1.
+
+    "Created: / 24-07-2014 / 19:54:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:11:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkCompletionEngineTests methodsFor:'tests - methods'!
+
+test_methods_01a    
+    | po_between_and |
+
+    codeView classHolder value: self class.
+    codeView codeAspect: #method. 
+    self complete:'foo
+    ^ 1 betwee┃'.
+
+    po_between_and := result detect:[:each | each isSmallSenseMethodPO and:[each selector == #between:and:]] ifNone:[ nil ].
+
+    self assert: po_between_and notNil.
+
+    po_between_and insert.
+
+    self assert: (codeView list at: 2) = '    ^ 1 between:  and:  '
+
+    "Created: / 07-03-2015 / 10:30:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkEditSupport.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,622 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+EditSupport subclass:#SmalltalkEditSupport
+	instanceVariableNames:'lastTypedKey0 lastTypedKey1 lastTypedKey2 lastTypedKey3'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk'
+!
+
+!SmalltalkEditSupport class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkEditSupport class methodsFor:'utilities'!
+
+indent: text by: level
+    ^ String streamContents:[ :out |
+        | in |
+
+        in := text readStream.
+        [ in atEnd ] whileFalse:[
+            in peek == Character cr ifTrue:[
+                out nextPut: in next.
+                out next: level put: Character space.
+            ] ifFalse:[
+                out nextPut: in next.
+            ].
+        ].
+    ]
+
+    "Created: / 04-05-2014 / 23:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+undent: stringOrStringCollection
+    | lines indent tabwidth ignoreIndentOfFirstLineIfZero indentOfFirstLineIsZero |
+
+    stringOrStringCollection isStringCollection ifTrue:[ 
+        ignoreIndentOfFirstLineIfZero := false.
+        stringOrStringCollection removeLast.
+        lines := stringOrStringCollection.
+    ] ifFalse:[
+        ignoreIndentOfFirstLineIfZero := true.
+        lines := stringOrStringCollection asStringCollection.
+    ].
+    tabwidth := (ListView userDefaultTabPositions = ListView tab4Positions) ifTrue:[ 4 ] ifFalse: [ 8 ].
+    indent := nil.
+    indentOfFirstLineIsZero := false.
+
+    1 to: lines size do:[:lineNo |
+        | line lineIndent |
+
+        line := lines at: lineNo.
+        lineIndent := line indexOfNonSeparator.
+        (lineIndent ~~ 0) ifTrue:[
+            indent isNil ifTrue:[
+                indent := ((lineIndent - 1) // tabwidth) * tabwidth.
+            ] ifFalse:[ 
+                indent := (((lineIndent - 1) // tabwidth) * tabwidth) min: indent.
+            ].
+            indent == 0 ifTrue:[
+                (lineNo == 1 and:[ignoreIndentOfFirstLineIfZero]) ifTrue:[
+                    indent := nil.
+                    indentOfFirstLineIsZero := true.
+                ] ifFalse:[
+                    ^ stringOrStringCollection isStringCollection
+                        ifTrue:[ stringOrStringCollection asStringWithoutFinalCR ]
+                        ifFalse:[ stringOrStringCollection ]
+                ].
+            ].
+        ].
+    ].
+    1 to: lines size do:[:lineNr |  
+        (lineNr ~~ 1 or:[indentOfFirstLineIsZero not]) ifTrue:[ 
+            lines at: lineNr put: ((lines at: lineNr) copyFrom: indent + 1).
+        ].
+    ].
+    ^ lines asStringWithoutFinalCR
+
+    "Created: / 04-05-2014 / 23:09:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-07-2014 / 23:24:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupport methodsFor:'accessing'!
+
+language
+    "superclass SmallSenseEditorSupport says that I am responsible to implement this method"
+
+    ^SmalltalkLanguage instance
+
+    "Modified: / 24-07-2013 / 23:46:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupport methodsFor:'accessing-classes'!
+
+completionEngineClass
+    ^ SmalltalkCompletionEngine
+
+    "Created: / 02-10-2013 / 13:30:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+scannerClass
+    "Returns a class to use for scanning lines. If nil, scanning is
+     not supported and scanLine* methods will return an empty array."
+
+    ^ Scanner
+
+    "Created: / 22-10-2013 / 00:39:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupport methodsFor:'editing'!
+
+electricInsert:stringOrLines advanceCursorBy:offsetOrNil
+    | ignore |
+
+    (stringOrLines isString and:[ stringOrLines first == lastTypedKey0 ]) ifTrue:[
+        ignore := stringOrLines copyFrom:2.
+    ].
+    ^ self
+            electricInsert:stringOrLines
+            advanceCursorBy:offsetOrNil
+            ignoreKeystrokes:ignore
+
+    "Created: / 20-01-2014 / 09:27:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsertSnippet
+    lastTypedKey0 == Character space ifTrue:[
+        ^ self electricInsertSnippetAfterSpace
+    ].
+    lastTypedKey0 == $: ifTrue:[
+        ^ self electricInsertSnippetAfterDoubleColon
+    ].
+    ^ false.
+
+    "Created: / 22-10-2013 / 02:55:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsertSnippetAfterDoubleColon
+    | tokens  lastToken0  lastValue0 |
+
+    tokens := self scanLineAtCursor.
+    tokens isEmptyOrNil ifTrue:[
+        ^ false
+    ].
+    lastToken0 := tokens at:(tokens size - 3).
+    lastToken0 = 'Error' ifTrue:[
+        ^ false
+    ].
+    (tokens last > textView cursorCol) ifTrue:[
+        ^ false
+    ].
+    ((lastToken0 == #Identifier)
+        and:[ (textView cursorCol - 1) == tokens last ])
+            ifTrue:[
+                lastValue0 := tokens at:tokens size - 2.
+                tokens size > 4 ifTrue:[
+                    (#( #do #select #reject #detect #contains #allSatisfy #anySatisfy )
+                        includes:lastValue0)
+                            ifTrue:[
+                                | collectionName iterationVariableName space part1 part2 |
+
+                                space := RBFormatter spaceAfterKeywordSelector ifTrue:[' '] ifFalse:[ '' ].
+                                iterationVariableName := 'each'.
+                                tokens size > 4 ifTrue:[
+                                    collectionName := tokens at:tokens size - 6.
+                                    iterationVariableName := self iterationVariableNameForCollectionNamed: collectionName.
+                                ].
+                                part1 := ':' , space , '[:' , iterationVariableName , ' | '.
+                                part2 := ' ]'.
+                                self electricInsert:part1 , part2 advanceCursorBy:part1 size.
+                                ^ true.
+                            ].
+                    RBFormatter spaceAfterKeywordSelector ifTrue:[
+                        self electricInsert:': '.
+                        ^ true.
+                    ]
+                ].
+            ].
+    ^ false.
+
+    "Created: / 22-10-2013 / 03:05:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 04-03-2015 / 07:54:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+electricInsertSnippetAfterSpace
+    | tokens  lastToken0  lastValue0 |
+
+    tokens := self scanLineAtCursor.
+    tokens isEmptyOrNil ifTrue:[
+        ^ false
+    ].
+    lastToken0 := tokens at:(tokens size - 3).
+    lastToken0 = 'Error' ifTrue:[
+        ^ false
+    ].
+    (tokens last > textView cursorCol) ifTrue:[
+        ^ false
+    ].
+    lastToken0 == #Keyword ifTrue:[
+        lastValue0 := tokens at:tokens size - 2.
+        tokens size > 4 ifTrue:[
+            (#( #do: #select: #reject: #detect: #contains: #allSatisfy: #anySatisfy: )
+                includes:lastValue0)
+                    ifTrue:[
+                        | collectionName  eachName  part1  part2 |
+
+                        eachName := 'each'.
+                        tokens size > 4 ifTrue:[
+                            ((collectionName := tokens at:tokens size - 6) last = $s) ifTrue:[
+                                (collectionName endsWith:'ses') ifTrue:[
+                                    eachName := collectionName copyButLast:2
+                                ] ifFalse:[
+                                    eachName := collectionName copyButLast:1
+                                ].
+                            ].
+                        ].
+                        part1 := ' [:' , eachName , ' | '.
+                        part2 := ' ]'.
+                        self electricInsert:part1 , part2 advanceCursorBy:part1 size.
+                        ^ true.
+                    ].
+        ]
+    ].
+    ^ false.
+
+    "Created: / 22-10-2013 / 03:00:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:02:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupport methodsFor:'event handling'!
+
+keyPress: key x:x y:y in: view
+
+    "Handles an event in given view (a subview of codeView).
+     If the method returns true, the event will not be processed
+     by the view."
+
+    view ~~ textView ifTrue:[ ^ false ].
+
+    (self keyPressIgnored: key) ifTrue:[
+        ^ true.
+    ].
+
+    lastTypedKey3 := lastTypedKey2.
+    lastTypedKey2 := lastTypedKey1.
+    lastTypedKey1 := lastTypedKey0.
+    lastTypedKey0 := key.
+
+    key == #CodeCompletion ifTrue:[
+        | controller |
+
+        (controller := self textView completionSupport) notNil ifTrue:[
+            ^ controller handleKeyPress:key x:x y:y
+        ].
+        ^ false
+    ].
+
+    key == #BackSpace ifTrue:[
+        backspaceIsUndo ifTrue:[
+             textView undo.
+             backspaceIsUndo := false.
+             electricInsertSuppressed := true.
+             ^ true.
+        ].
+    ].
+    backspaceIsUndo := false.
+
+    key == #Paste ifTrue:[
+        ^ self keyPressPaste.
+    ].
+
+    electricInsertSuppressed ifTrue:[ 
+        (key isCharacter and:[ key isSeparator ]) ifTrue:[ 
+            electricInsertSuppressed := false.
+        ].
+    ].
+
+    UserPreferences current smallSenseElectricEditSupportEnabled ifFalse:[ ^ false ]. 
+
+    key == $^ ifTrue:[
+        ^ self keyPressReturnToken
+    ].
+    key == #Return ifTrue: [
+        ^ self keyPressReturn
+    ].
+
+    key == $: ifTrue: [
+        ^ self keyPressDoubleColon.
+    ].
+
+    key == $= ifTrue: [
+        ^ self keyPressEqual
+    ].
+
+    key == Character space ifTrue:[
+        ^ self electricInsertSnippet
+    ].
+
+    key == $[ ifTrue:[
+        ^ self keyPressOpenBracket.
+    ].
+
+    ^ false.
+
+    "Created: / 07-03-2010 / 09:36:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 04-05-2015 / 00:05:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressDoubleColon
+    electricInsertSuppressed ifTrue:[ ^ false ].
+    ^ self electricInsertSnippetAfterDoubleColon
+
+    "Created: / 22-10-2013 / 03:08:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-03-2015 / 17:07:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressEqual
+    | line |
+
+    electricInsertSuppressed ifTrue:[ ^ false ].      
+    line := textView listAt:textView cursorLine.
+    line isNil ifTrue:[ ^ false ].
+    line := line string.
+    line size > textView cursorCol ifTrue: [ ^ false ].
+    line size < (textView cursorCol - 1) ifTrue: [ ^ false ].
+    (line at: textView cursorCol - 1) == $: ifTrue: [
+        self electricInsert:'= '.
+        ^ true
+    ].
+    ^ false
+
+    "Created: / 22-10-2013 / 11:01:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-03-2015 / 17:07:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressOpenBracket
+    "Opening `[` has been pressed. Complete closing bracket and position
+     cursor in between them, but only of there's no other text on current line"
+
+    | line |
+
+    electricInsertSuppressed ifTrue:[ ^ false ].      
+    line := textView listAt: textView cursorLine.
+    line notNil ifTrue:[
+        line := line string.
+        line size > textView cursorCol ifTrue: [
+            line size downTo: textView cursorCol - 1 do:[:i |
+                (line at:i) == Character space ifFalse:[ ^ false ].
+            ]
+        ].
+    ].
+
+    RBFormatter spaceAfterBlockStart ifTrue:[
+        RBFormatter spaceBeforeBlockEnd ifTrue:[
+            self electricInsert:'[  ]' advanceCursorBy: 2 ignoreKeystrokes: nil.
+        ] ifFalse:[
+            self electricInsert:'[ ]' advanceCursorBy: 2 ignoreKeystrokes: nil.
+        ].
+    ] ifFalse:[
+        RBFormatter spaceBeforeBlockEnd ifTrue:[
+            self electricInsert:'[ ]' advanceCursorBy: 1 ignoreKeystrokes: nil .
+        ] ifFalse:[
+            self electricInsert:'[]' advanceCursorBy: 1 ignoreKeystrokes: nil.
+        ].
+    ].
+    ^ true.
+
+    "Created: / 22-01-2014 / 21:35:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 06:33:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressPaste
+    | textSelected textPasted currentLineNo currentLine currentLineIsEmpty |
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled ifFalse:[ ^ false ].
+
+    electricInsertSuppressed ifTrue:[ ^ false ].      
+    textView checkModificationsAllowed ifTrue:[
+        textSelected := textPasted := textView getTextSelectionOrTextSelectionFromHistory.
+        currentLineNo := textView currentLine.
+        currentLineIsEmpty := true.
+        ((currentLineNo > textView list size)
+            or:[ (currentLine := textView list at: currentLineNo) isNil
+                or:[ (currentLineIsEmpty := currentLine indexOfNonSeparator == 0) ]]) ifTrue:[
+                    | indent |
+
+                    currentLineIsEmpty ifTrue:[
+                        indent := textView leftIndentForLine: currentLineNo.
+                        textView setCursorCol: indent + 1.
+                    ].
+                    textPasted := self class undent: textPasted.
+                    textPasted := self class indent: textPasted by: textView cursorCol - 1.
+
+                ].
+
+        textView undoablePasteOrReplace: textPasted info: nil.
+    ].
+    ^ true
+
+    "Created: / 03-05-2014 / 01:08:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-03-2015 / 17:07:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressReturn
+    | line tokens c i t currentLineIndent closingBracketIndex |
+
+    electricInsertSuppressed ifTrue:[ ^ false ].      
+    line := textView listAt: textView cursorLine.
+    line isNil ifTrue:[ ^ false ].
+    line := line string.
+
+    "/ Check whether there is any text afer cursor
+    "/ except of single closing `]`. If there's some text
+    "/ don't do anything smart. If there's only single closing
+    "/ ']', then remeber it.
+    closingBracketIndex := 0.
+    line size > textView cursorCol ifTrue: [
+        line size downTo: ((textView cursorCol - 1) max: 1) do:[:i |
+            (c :=line at:i) == Character space ifFalse:[
+                (c == $] and:[closingBracketIndex == 0]) ifTrue:[
+                    closingBracketIndex := i.
+                ] ifFalse:[
+                    ^ false
+                ].
+            ].
+        ]
+    ].
+
+    (line indexOfAny:'[|/') == 0 ifTrue:[ ^ false ].
+
+    "/ Insert "/ at the beggining of the line if current line starts with "/
+    i := currentLineIndent := line indexOfNonSeparator.
+    (i ~~ 0 and:[ i < line size and:[(line at:i) == $" and:[(line at:i + 1) == $/]]]) ifTrue:[
+        "/ OK, current line contains eol-comment. Split into
+        "/ two actions so backspace deletes only the inserted '"/ ' text
+        self electricInsert:#( '' '' ) advanceCursorBy:(1 @ i).
+        self electricInsert:'"/ '.
+        ^ true
+    ].
+
+    "/ Now insert/reindent closing bracket ( ']' ) for block, byt only
+    "/ if current preference is C-style blocks
+    RBFormatter cStyleBlocks ifFalse:[ ^ false ].
+    "/ There are two possible cases:
+    "/ (i)  there is no single closing bracket on the line, then
+    "/      add closing ] but only iff last typed character is
+    "/      either [ or |  !!!!!!!! Otherwise we would get annoying behaviour
+    "/      when there's already valid code and someone position cursor after
+    "/      opening bracket and press enter.
+    "/ (ii) there's single closing bracket on current line
+    "/      (closingBracketIndex is non-zero)
+    (closingBracketIndex == 0 and:[('[|' includes: lastTypedKey1) not]) ifTrue:[ ^ false ].
+
+    i := textView cursorCol - 1.
+    [ (line at: i) isSeparator and:[i > 0] ] whileTrue:[ i := i - 1 ].
+    i == 0 ifTrue:[ ^ false ].
+    (line at: i) == $[ ifTrue:[
+        self electricDo:[
+            closingBracketIndex ~~ 0 ifTrue:[
+                self electricDeleteCharacterAtCol: closingBracketIndex
+            ].
+            self electricInsertBlockOpenedBy:nil closedBy:'].'.
+        ].
+        ^ true
+    ].
+    tokens := self tokensAtCursorLine.
+    tokens isEmpty ifTrue:[ ^ false ].
+    i := tokens size.
+    t := tokens at: i.
+    t == $[ ifTrue:[
+        self electricDo:[
+            closingBracketIndex ~~ 0 ifTrue:[
+                self electricDeleteCharacterAtCol: closingBracketIndex
+            ].
+            self electricInsertBlockOpenedBy:nil closedBy:'].'.
+        ].
+        ^ true
+    ].
+    t == $| ifTrue:[
+        i := i - 1.
+        [ i > 1 and:[ (tokens at: i) == #Identifier and:[ (tokens at: i - 1) == $: ]] ] whileTrue:[ i := i - 2 ].
+
+        (i ~~ 0 and: [(tokens at: i) == $[]) ifTrue:[
+            self electricDo:[
+                closingBracketIndex ~~ 0 ifTrue:[
+                    self electricDeleteCharacterAtCol: closingBracketIndex
+                ].
+                self electricInsertBlockOpenedBy:nil closedBy:'].'.
+            ].
+            ^ true
+        ].
+        i := tokens size  - 1.
+        [ i > 0 and:[ (tokens at: i) == #Identifier ] ] whileTrue:[ i := i - 1 ].
+        (i ~~ 0 and: [(tokens at: i) == $|]) ifTrue:[
+            RBFormatter emptyLineAfterTemporaries ifTrue:[
+                self electricDo:[
+                    closingBracketIndex ~~ 0 ifTrue:[
+                        self electricDeleteCharacterAtCol: closingBracketIndex
+                    ].
+                    self electricInsert:#( '' '' '' ) advanceCursorBy:2 @ currentLineIndent.
+                ].
+                ^ true
+            ]
+        ]
+    ].
+    ^ false.
+
+    "Created: / 25-07-2013 / 00:02:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-03-2015 / 17:07:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+keyPressReturnToken
+    electricInsertSuppressed ifTrue:[ ^ false ].      
+    RBFormatter spaceAfterReturnToken ifTrue:[
+        self electricDo:[
+            textView insertStringAtCursor:'^ '
+        ].
+        ^ true
+    ].
+    ^ false
+
+    "Created: / 24-07-2013 / 23:59:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-03-2015 / 17:07:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupport methodsFor:'initialization'!
+
+initializeForService: anEditService
+    super initializeForService: anEditService.
+    anEditService textView autoIndent:true.
+
+    "Created: / 27-09-2013 / 13:22:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 23:59:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupport methodsFor:'private'!
+
+iterationVariableNameForCollectionNamed: collectionName
+    | eachName |
+
+    eachName := 'each'.
+    ((collectionName) last = $s) ifTrue:[
+        (collectionName endsWith:'ses') ifTrue:[
+            eachName := collectionName copyButLast:2
+        ] ifFalse:[
+            eachName := collectionName copyButLast:1
+        ].
+        UserPreferences current smallSenseSmalltalkIterationVariableNamePrefixWithEach ifTrue:[ 
+            eachName := 'each' , eachName capitalized.
+        ].
+        eachName size > UserPreferences current smallSenseSmalltalkIterationVariableNameMaxLength ifTrue:[ 
+            eachName := 'each'.
+        ].
+    ].
+    ^ eachName
+
+    "Created: / 04-03-2015 / 07:52:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+tokensAtCursorLine
+    | line scanner token |
+
+    line := (textView listAt: textView cursorLine) string.
+    line := line copyTo: textView cursorCol - 1.
+    line isEmpty ifTrue:[ ^ #() ].
+    scanner := Scanner for: line.
+    ^ OrderedCollection streamContents:[:tokens |
+        [ token := scanner nextToken.token ~~ #EOF ] whileTrue:[
+            tokens nextPut: token.
+        ].
+    ].
+
+    "Created: / 25-07-2013 / 00:07:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 12-02-2015 / 00:02:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupport class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkEditSupportTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,454 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+EditSupportTests subclass:#SmalltalkEditSupportTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!SmalltalkEditSupportTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkEditSupportTests methodsFor:'accessing-classes'!
+
+editSupportClass
+    "superclass SmallSense::EditSupportTests says that I am responsible to implement this method"
+
+    ^ SmalltalkEditSupport
+
+    "Created: / 23-07-2014 / 07:16:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupportTests methodsFor:'tests - completion'!
+
+test_complete_if_unambiguous_01    
+
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.  
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService'.
+    codeView setCursorCol: 12.
+
+    codeViewInteractor type: #(Return Tab).
+    codeViewInteractor type: 't'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'h'.
+    self assert: (codeView list at: 2) = '    thisContext'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'i'.
+    codeViewInteractor type:'sContext'.
+    self assert: (codeView list at: 2) = '    thisContext'.
+
+    "Created: / 23-07-2014 / 23:38:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-05-2015 / 23:50:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_if_unambiguous_02
+
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.  
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService'.
+    codeView setCursorCol: 12.
+
+    codeViewInteractor type: #(Return Tab).
+    codeViewInteractor type: 't'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'h'.
+    self assert: (codeView list at: 2) = '    thisContext'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'is receiver'.
+    self assert: (codeView list at: 2) = '    thisContext receiver'.
+
+    "Created: / 11-08-2014 / 15:00:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_if_unambiguous_03
+
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.  
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService'.
+    codeView setCursorCol: 12.
+
+    codeViewInteractor type: #(Return Tab).
+    codeViewInteractor type: 't'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'h'.
+    self assert: (codeView list at: 2) = '    thisContext'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'isValue'.
+    self assert: (codeView list at: 2) = '    thisValue'.
+
+    "Created: / 11-08-2014 / 15:01:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_complete_if_unambiguous_04
+
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.  
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService'.
+    codeView setCursorCol: 12.
+
+    codeViewInteractor type: #(Return Tab).
+    codeViewInteractor type: 't'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'h'.
+    self assert: (codeView list at: 2) = '    thisContext'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: #(BackSpace).
+    self assert: (codeView list at: 2) = '    t'.
+    codeViewInteractor type: 'h'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    th'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'e := t'.
+    Delay waitForMilliseconds: 250.
+    codeViewInteractor type: 'h'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    the := thisContext'.
+
+    "Created: / 03-03-2015 / 17:01:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupportTests methodsFor:'tests - electric snippets'!
+
+test_electric_snippet_do_01
+
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.  
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:[:snippet |  ]'.
+    codeViewInteractor type: #(BackSpace).
+    self assert: (codeView list at: 2) = '    snippets do'.
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:'.
+
+    "Created: / 04-03-2015 / 05:54:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-05-2015 / 21:59:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_electric_snippet_do_02
+
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.  
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:[:snippet |  ]'.
+    codeViewInteractor type: 'aBlock'.
+    self assert: (codeView list at: 2) = '    snippets do: aBlock'.
+
+    "Created: / 04-03-2015 / 06:11:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-05-2015 / 21:59:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_electric_snippet_do_03
+
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.  
+    UserPreferences current smallSenseSmalltalkIterationVariableNamePrefixWithEach: true.
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:[:eachSnippet |  ]'.
+
+    "Created: / 04-03-2015 / 08:13:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-05-2015 / 21:59:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_electric_snippet_do_04
+
+    UserPreferences current smallSenseElectricEditSupportEnabled: true.  
+    UserPreferences current smallSenseSmalltalkIterationVariableNameMaxLength: 5.
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:[:each |  ]'.
+
+    "Created: / 04-03-2015 / 08:14:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-05-2015 / 21:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_electric_snippet_do_05
+
+    UserPreferences current smallSenseElectricEditSupportEnabled: false.
+    codeView editedMethodOrClass: self class.
+    codeView contents:'editService
+    snippets do'.
+    codeView setCursorLine: 2; setCursorCol: 16.
+
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:'.
+    codeViewInteractor type: #(BackSpace).
+    self assert: (codeView list at: 2) = '    snippets do'.
+    codeViewInteractor type: ':'.
+    Delay waitForMilliseconds: 250.
+    self assert: (codeView list at: 2) = '    snippets do:'.
+
+    "Created: / 02-05-2015 / 21:58:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkEditSupportTests methodsFor:'tests - indent-on-paste'!
+
+test_indent_on_paste_01a
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+
+    ].
+    self halt.'.
+
+    codeView selectFromLine: 5 col: 5 toLine: 5 col: 14.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '        self halt.'.
+
+    "Created: / 23-07-2014 / 09:46:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_01b
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+
+    ].
+    self halt.'.
+
+    codeView selectFromLine:5 col:1 toLine:6 col:0.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '        self halt.'.
+
+    "Created: / 23-07-2014 / 09:47:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_02a
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+
+    ].
+    param isNil ifTrue:[
+        self halt.
+    ]'.
+
+    codeView selectFromLine: 5 col: 5 toLine: 7 col: 5.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '        param isNil ifTrue:['.
+    self assert: (codeView list at: 4) = '            self halt.'.
+    self assert: (codeView list at: 5) = '        ]'.
+
+    "Created: / 23-07-2014 / 10:20:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_02b
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+
+    ].
+    param isNil ifTrue:[
+        self halt.
+    ]'.
+
+    codeView selectFromLine: 5 col: 1 toLine: 8 col: 0.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '        param isNil ifTrue:['.
+    self assert: (codeView list at: 4) = '            self halt.'.
+    self assert: (codeView list at: 5) = '        ]'.
+
+    "Created: / 23-07-2014 / 10:20:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_03a
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+
+    ].
+    param isNil ifTrue:[
+        self halt.
+    ]'.
+
+    codeView selectFromLine: 5 col: 5 toLine: 6 col: 18.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '        param isNil ifTrue:['.
+    self assert: (codeView list at: 4) = '            self halt.'.
+
+    "Created: / 23-07-2014 / 23:28:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_03b
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+
+    ].
+    param isNil ifTrue:[
+        self halt.
+    ]'.
+
+    codeView selectFromLine: 5 col: 1 toLine: 7 col: 0.
+
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '        param isNil ifTrue:['.
+    self assert: (codeView list at: 4) = '            self halt.'.
+
+    "Created: / 23-07-2014 / 23:28:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_04a
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+        Transcript showCR:''XXX''.
+    ].
+    self halt.'.
+
+    codeView selectFromLine: 5 col: 5 toLine: 5 col: 14.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '    self halt.    Transcript showCR:''XXX''.'.
+
+    "Created: / 24-07-2014 / 10:18:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_04b
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+        Transcript showCR:''XXX''.
+    ].
+    self halt.'.
+
+    codeView selectFromLine: 5 col: 5 toLine: 6 col: 0.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '    self halt.'.
+    self assert: (codeView list at: 4) = '    Transcript showCR:''XXX''.'.
+
+    "Created: / 24-07-2014 / 10:21:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_indent_on_paste_04c
+
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    codeView contents:'test
+    Debug ifTrue:[ 
+        Transcript showCR:''XXX''.
+    ].
+    self halt.'.
+
+    codeView selectFromLine: 5 col: 5 toLine: 6 col: 0.
+
+    codeViewInteractor type: #Cut.
+    codeViewInteractor type: #(CursorUp CursorUp CursorRight CursorRight CursorRight CursorRight).
+    codeViewInteractor type: #Paste.
+
+    self assert: (codeView list at: 3) = '        self halt.'.
+    self assert: (codeView list at: 4) = 'Transcript showCR:''XXX''.'.
+
+    "Created: / 24-07-2014 / 10:22:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-08-2014 / 14:26:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkInferencer.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,714 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#SmalltalkInferencer
+	instanceVariableNames:'type class classInfo source parser parserClass tree environment'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types-Inference'
+!
+
+SmalltalkParseNodeVisitor subclass:#Phase1
+	instanceVariableNames:'classInfo sends types'
+	classVariableNames:''
+	poolDictionaries:'SmallSense::SmalltalkInferencerParameters'
+	privateIn:SmalltalkInferencer
+!
+
+SmalltalkParseNodeVisitor subclass:#Phase2
+	instanceVariableNames:'classInfo'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:SmalltalkInferencer
+!
+
+SmalltalkParseNodeVisitor subclass:#Phase3
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:SmalltalkInferencer
+!
+
+!SmalltalkInferencer class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    A heart of SmallSense - a type inferencer. For given class
+    and method source, instance of inferences walks the parse tree
+    and annotate each node with inferred type.
+
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!SmalltalkInferencer class methodsFor:'instance creation'!
+
+forClass: class methodSource: source
+
+    ^self new class: class source: source
+
+    "Created: / 26-11-2011 / 12:45:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forClass: class selector: selector
+
+    ^self new class: class selector: selector.
+
+    "Created: / 26-11-2011 / 12:44:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forExpression: source
+
+    ^self new expression: source.
+
+    "Created: / 04-10-2013 / 08:12:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+forMethod: method
+
+    ^self new method: method.
+
+    "Created: / 26-11-2011 / 12:45:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer methodsFor:'accessing'!
+
+environment
+    ^ environment
+!
+
+environment:something
+    environment := something.
+!
+
+klass
+    ^ class
+
+    "Created: / 26-11-2011 / 17:30:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+manager
+
+    ^Manager instance
+
+    "Created: / 27-11-2011 / 16:16:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parser
+    ^ parser
+!
+
+parserClass
+    ^ parserClass
+!
+
+parserClass:aClass
+    parserClass := aClass.
+!
+
+source
+    ^ source
+!
+
+tree
+    ^ tree
+! !
+
+!SmalltalkInferencer methodsFor:'initialization'!
+
+class: cls selector: sel
+
+    | m |
+    m := cls >> sel.
+    m isNil ifTrue:[
+        self error: 'No method found'.
+    ].
+    self method: m.
+
+    "Created: / 26-11-2011 / 12:47:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+class: cls source: src
+
+    type isNil ifTrue:[
+        "/ Guess...
+        type := cls notNil ifTrue:[ #method ] ifFalse:[ #expression ]
+    ].
+    class := cls ? UndefinedObject.
+    classInfo := self manager infoForClass: class.
+    source := src.
+
+    "Created: / 26-11-2011 / 14:46:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 08:31:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+expression: expression
+
+    type := #expression.
+    self class: nil source: expression.
+
+    "Created: / 04-10-2013 / 08:14:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+method: method
+
+    type := #method.
+    self class: method mclass source: method source.
+
+    "Created: / 26-11-2011 / 12:48:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 08:13:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer methodsFor:'private'!
+
+infer
+
+
+    Phase1 process: tree in: class.
+    Phase2 process: tree in: class.
+
+    "
+    (SmallSenseParseNodeInspector new node: tree source: source) open
+    "
+
+    "Created: / 26-11-2011 / 12:51:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 05-08-2014 / 14:04:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parse
+
+    parserClass isNil ifTrue:[
+        parserClass := class parserClass.
+    ].
+    type == #method ifTrue:[
+        parser := parserClass
+                    parseMethod: source in: class
+                    ignoreErrors:true
+                    ignoreWarnings:true.
+        tree := parser tree.
+    ] ifFalse:[
+        type == #expression ifTrue:[
+            parser := parserClass for: source.
+            tree := parser
+                        parseExpressionWithSelf:nil
+                        notifying:nil
+                        ignoreErrors:false
+                        ignoreWarnings:false
+                        inNameSpace:nil.
+            parser tree: tree.
+        ].
+    ].
+
+    "Created: / 26-11-2011 / 12:51:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 08:15:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer methodsFor:'processing'!
+
+process
+
+    "Actually infer types. Returns an annotated method tree.
+     The tree is also stored in an instance variable, so it
+     may be obtained form receiver any time by asking for #tree."
+
+    [
+        self parse.
+    ] on: Error do:[:ex|
+        Transcript showCR: ex description.
+        ^ self.
+    ].
+    tree notNil ifTrue:[
+        self infer.
+    ].
+    ^tree
+
+    "Created: / 26-11-2011 / 12:50:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-03-2014 / 19:00:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer::Phase1 class methodsFor:'documentation'!
+
+documentation
+"
+    Inferencing phase 1: guess type of variables based on message sends
+    (idea taken from RoelTyper).
+
+    Also, assign types for known variables (globals, literals, pseudo variables)
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!SmalltalkInferencer::Phase1 methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+    sends := Dictionary new.
+    types := Dictionary new.
+
+    "/ super initialize.   -- commented since inherited method does nothing
+
+    "Modified: / 26-11-2011 / 19:31:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer::Phase1 methodsFor:'private'!
+
+rootsUnderstanding: selectors
+    "When the set of selectors is not empty, answer a set of the highest possible classes in the system that implement all the selectors.
+     When the set of selectors is empty, return the empty set."
+
+    | initialClasses nextClasses traverseStack next |
+    selectors isEmpty ifTrue: [^OrderedCollection new].
+    nextClasses := OrderedCollection with: Object.
+    traverseStack := OrderedCollection new: 1000.
+
+    selectors
+        do:
+            [:selector |
+            initialClasses := nextClasses.
+            nextClasses := OrderedCollection new.
+            initialClasses
+                do:
+                    [:initialClass |
+                    "inline canUnderstand: for performance"
+                    |cl|
+                    cl := initialClass.
+                    [(cl == nil) or: [(cl methodDictionary includesKey: selector)]] whileFalse: [cl := cl superclass].
+                    (cl == nil)
+                        ifFalse: [nextClasses addLast: initialClass]
+                        ifTrue:
+                            [|size|
+                            traverseStack reset.
+                            traverseStack addLast: initialClass.
+                            size := 1.
+                            "(traverseStack isEmpty) removed for performance"
+                            [size = 0]
+                                whileFalse:
+                                    [
+                                    "(traverseStack removeFirst) removed for performance"
+                                    next := traverseStack removeFirst.
+                                    size := size -1.
+                                    next
+                                        subclassesDo:
+                                            [:subcl |
+                                            "(subcl includesSelector: selector) removed for performance"
+                                            (subcl methodDictionary includesKey: selector)
+                                                ifTrue: [nextClasses addLast: subcl]
+                                                ifFalse: [traverseStack addLast: subcl. size := size + 1]]]]]].
+    ^nextClasses
+
+    "Modified: / 24-11-2010 / 14:39:35 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 26-11-2011 / 14:01:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 18-09-2013 / 01:22:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer::Phase1 methodsFor:'processing'!
+
+process: tree in: cls
+
+    self process: tree in: cls info: (Manager instance infoForClass: cls)
+
+    "Created: / 26-11-2011 / 13:48:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+process: tree in: cls info: clsInfo
+
+     | i c def prereqs |
+
+    class := cls.
+    classInfo := clsInfo.
+
+    "/ Do not process if class is troublesome
+    classInfo isErrorneous ifTrue:[ 
+        ^ self.
+    ].
+    "Fill types with cached data..."
+
+    c := class.
+    i := classInfo.
+    [ c notNil and:[i notNil] ] whileTrue:[
+        c instVarNames do:[:nm|
+            types at: nm put: (i infoForInstvar: nm)
+        ].
+        c := c superclass.
+        i := i superclassInfo.
+    ].
+
+    self visit:tree.
+
+
+    prereqs := nil.
+    def := ProjectDefinition definitionClassForPackage: class package createIfAbsent: false.
+    def notNil ifTrue:[
+        prereqs := def effectivePreRequisites.
+    ].
+
+
+    "Now, infer variable types based on collected sends"
+    sends keysAndValuesDo:[:varName :sentSelectors|
+        (types includesKey: varName) ifTrue:[
+            | classes union |
+            classes := (self rootsUnderstanding: sentSelectors) collect:[:each |  ClassType new klass: each ].
+
+            prereqs notNil ifTrue:[
+                "/ Make classes in packages on which method's package does **NOT** depend
+                "/ less likely to be correct (by lowering their trustfullness)
+                classes do:[:each |
+                    (prereqs includes: each klass package) ifTrue:[
+                        each trustfullnessAdd: -20
+                    ].
+                ]
+            ].
+            union := UnionType new.
+            union addType: (types at: varName) type.
+            union addTypes: classes.
+            (types at: varName) type: union
+        ].
+    ].
+
+    "Created: / 27-11-2011 / 16:22:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 21-11-2014 / 17:19:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer::Phase1 methodsFor:'visiting'!
+
+visitBlockNode:anObject
+    | type |
+
+    super visitBlockNode:anObject.
+    type := Type withClass: Block.
+    type trustfullness: 100.
+    anObject inferedType: type.
+
+    "Created: / 26-11-2011 / 14:46:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitConstantNode:anObject
+    "Type of a constant is trivially its value class"
+
+    | type |
+
+    super visitConstantNode: anObject.
+    type := (Type withClass: anObject value class).
+    type trustfullness: 100.
+    anObject inferedType: type.
+
+    "Created: / 26-11-2011 / 13:55:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitMessageNode:anObject
+
+    | rec |
+
+    super visitMessageNode: anObject.
+
+    (rec := anObject receiver) isVariableNode ifTrue:[
+        "We don't have to infer types for global/class variables"
+        (rec isGlobalVariable or:[rec isClassVariable]) ifTrue:[
+            "/ Check for pattern: `Smalltalk at: #ClassName`
+            (rec name = 'Smalltalk' and:[anObject arguments conform:[:node | node isConstant ] ]) ifTrue:[
+                | result |
+
+                "Here, evaluate the node, but only for certain known selectors!!
+                 (think of selector #exit :-) - you'll laugh, but it hit me back hard
+                 couple times...
+                "
+                (#(	at:
+                	classNamed:
+                	"/ add more...
+                ) includes:anObject selector) ifTrue:[
+                	[
+		                result := anObject evaluate.
+	                	result notNil ifTrue:[
+		                    anObject inferedType: ((Type withClass: result class) trustfullness: 100)
+		                ]
+	                ] on: Error do:[
+	                	"/pass
+	                ]
+	            ]
+            ].
+        ] ifFalse:[
+            (sends at: rec name ifAbsentPut:[Set new]) add: anObject selector.
+        ].
+    ].
+
+    "Created: / 26-11-2011 / 13:02:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 07:56:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitSelfNode:anObject
+    | type |
+
+    super visitSelfNode:anObject.
+    type := Type withClass: class.
+    type trustfullness: 100.
+    anObject inferedType:type
+
+    "Created: / 26-11-2011 / 14:43:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-09-2013 / 01:25:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitSuperNode:anObject
+    | superclass type |
+
+    super visitSuperNode:anObject.
+    superclass := class superclass.    
+    type := superclass notNil ifTrue:[ Type withClass: class superclass ] ifFalse:[ Type unknown ].
+    type trustfullness: 100.
+    anObject inferedType:type
+
+    "Created: / 26-11-2011 / 14:44:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-11-2014 / 22:17:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitVariableNode:anObject
+
+    | t |
+
+    "Following code ensures, that all variable nodes refering same
+     variable shares the inferred type"
+    t := types at: anObject name ifAbsentPut:[Type unknown].
+    anObject inferedType: t.
+
+    anObject isGlobalVariable ifTrue:[
+        | globalName global globalClass |
+
+        globalName := anObject name asSymbolIfInterned.
+        globalName notNil ifTrue:[
+            global := Smalltalk at: globalName.
+
+            "/ Special hack for JAVA - its actually a JavaPackage...
+            global == (Smalltalk at: #JAVA) ifTrue:[
+                global := JavaPackage
+            ].
+            globalClass := global class.
+
+            global notNil ifTrue:[
+                t addClass:  globalClass.
+                t trustfullness: 100.
+            ].
+        ].
+        ^self.
+    ].
+    anObject isClassVariable ifTrue:[
+        t addClass: (class theNonMetaclass classVarAt: anObject name asSymbol) class.
+        t trustfullness: 100.
+        ^self.
+    ].
+
+    "Created: / 26-11-2011 / 13:31:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 02-12-2014 / 22:06:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer::Phase2 class methodsFor:'documentation'!
+
+documentation
+"
+    Inferencing phase 2: Guess types based on 'known' selectors, like #==, #=, #class, #new: and so on...
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!SmalltalkInferencer::Phase2 methodsFor:'visiting'!
+
+visitMessageNode:aMessageNode
+
+    | selector |
+
+    super visitMessageNode: aMessageNode.  
+
+    selector := aMessageNode selector.
+    "/ Some selectors are known / expected  to return boolean
+    (#( #== #~~ #= #~= #< #<= #=> #> #contains: includes: includesKey: #anySatisfy: #allSatisfy:) includes: selector) ifTrue:[
+        aMessageNode inferedType: (Type withClass: Boolean).
+        ^ self.
+    ].
+
+    "/ Some selectors are known / expected  to return some numerical values
+    (#( #+ #- #* #/ #// #\\ ) includes: selector) ifTrue:[
+        aMessageNode inferedType: (Type withClass: Number).
+        ^ self.
+    ].
+
+
+    "/ #new / #basicNew: conventionally returns an instance of the class, if receiver is a class.
+    (#(#new: #basicNew:) includes: selector) ifTrue:[
+        | rec type |
+        rec := aMessageNode receiver.
+        (rec isSelf and:[class isMetaclass]) ifTrue:[
+            type := Type withClass: class theNonMetaclass.
+            type trustfullnessAdd: 50.
+            aMessageNode inferedType: type.
+            ^self.
+        ].
+
+        type := aMessageNode receiver inferedType instanceSide.
+        aMessageNode inferedType: type.
+        ^self.
+    ].
+
+    "Created: / 05-08-2014 / 14:03:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 26-09-2014 / 11:20:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitUnaryNode:anObject
+
+    | type sel rec classes |
+
+    super visitUnaryNode:anObject.
+
+    sel := anObject selector.
+
+    "/ #class should always return a class of the receiver...
+    sel == #class ifTrue:[
+        type := anObject receiver inferedType classSide.
+        anObject inferedType: type.
+        ^self.
+    ].
+
+    "/ #new / #basicNew: conventionally returns an instance of the class, if receiver is a class.
+    (sel == #new or:[sel == #basicNew]) ifTrue:[
+        rec := anObject receiver.
+        (rec isSelf and:[class isMetaclass]) ifTrue:[
+            type := Type withClass: class theNonMetaclass.
+            type trustfullnessAdd: 50.
+            anObject inferedType: type.
+            ^self.
+        ].
+
+        type := anObject receiver inferedType instanceSide.
+        anObject inferedType: type.
+        ^self.
+    ].
+
+    rec := anObject receiver.
+    classes := rec inferedType classes.
+    classes size == 1 ifTrue:[
+        "/ Special hack for Java, when code is like
+        "/ `JAVA java lang reflect`
+        classes anElement == JavaPackage class ifTrue:[
+            (JAVA notNil and:[anObject selector first isUppercase]) ifTrue:[
+                | jclass |
+
+                "/ fetch an accessor...
+                [
+                    jclass := anObject evaluate.
+                    "/ fetch the class...
+                    jclass := JavaVM classNamed: jclass fullName definedBy: JavaVM systemClassLoader.
+                    jclass notNil ifTrue:[
+                        anObject inferedType: (Type withClass: jclass class).
+                    ] ifFalse:[
+                        anObject inferedType: (Type withClass: JavaClass class).
+                    ].
+                ] on: Error do:[
+                    "/ ignore...
+                ]
+            ] ifFalse:[
+                anObject inferedType: (Type withClass: JavaPackage class).
+            ].
+        ].
+    ].
+
+    "Created: / 27-11-2011 / 15:49:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-10-2013 / 11:07:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 05-08-2014 / 13:56:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencer::Phase3 class methodsFor:'documentation'!
+
+documentation
+"
+    Phase 3: guess types based on naming conventions. This is mainly to process
+    parameters in form of aString or aStringOrBoolean...
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!SmalltalkInferencer class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkInferencerParameters.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,74 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SharedPool subclass:#SmalltalkInferencerParameters
+	instanceVariableNames:''
+	classVariableNames:'UnionTypeMaxSize UnionTypeReduceThreshold'
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types-Inference'
+!
+
+!SmalltalkInferencerParameters class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkInferencerParameters class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    UnionTypeMaxSize := 15.
+    UnionTypeReduceThreshold := 5.
+
+    "Modified: / 01-03-2014 / 23:23:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkInferencerParameters class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
+
+SmalltalkInferencerParameters initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkLintService.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,442 @@
+"
+ COPYRIGHT (c) 2006 by eXept Software AG
+	      All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Tools::BackgroundSourceProcessingService subclass:#SmalltalkLintService
+	instanceVariableNames:'rulesHolder rules highlighter support annotations
+		annotationsSequenceNumber'
+	classVariableNames:'Debugging'
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Lint'
+!
+
+!SmalltalkLintService class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2006 by eXept Software AG
+	      All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.   This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+! !
+
+!SmalltalkLintService class methodsFor:'accessing'!
+
+debugging
+    ^Debugging == true
+
+    "Created: / 17-02-2012 / 00:48:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+debugging: aBoolean
+
+    Debugging := aBoolean
+
+    "Created: / 16-02-2012 / 16:22:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+    "Answers short label - for UI"
+
+    ^'SmallSense - Static Checking'
+
+    "Created: / 07-03-2010 / 14:00:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 27-07-2013 / 22:36:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+priority
+    "Answers a priority of the service. Services with higher priority
+     will get the event notification before ones with lower priority.
+     Therefore, a lower-priority service might not get the event if high
+     priority service processes it"
+
+    ^ 10
+
+    "Created: / 01-02-2012 / 10:29:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService class methodsFor:'queries'!
+
+isUsefulFor:aCodeView
+    "this filters useful services.
+     must be redefined to return true in subclasses (but each class must do it only
+     for itself - not for subclasses"
+
+    ^ self == SmalltalkLintService
+
+    "Created: / 24-07-2013 / 11:35:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-09-2013 / 15:26:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService class methodsFor:'testing'!
+
+isAvailable
+
+    ^UserPreferences current smallSenseEnabled
+
+    "Created: / 04-02-2012 / 22:20:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService methodsFor:'accessing'!
+
+annotationAtLine: lineNo
+    | anns |
+
+    (anns := self annotations) notNil ifTrue:[ 
+        ^ anns detect:[:annotation | annotation line = lineNo] ifNone:[ nil ]
+    ].
+    ^ nil
+
+    "Created: / 30-01-2012 / 21:06:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 15:40:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+annotations
+    (highlighter notNil and:[ highlighter sequenceNumber ~~ annotationsSequenceNumber ]) ifTrue:[ 
+        | rulesToIntervalsMap annotationsPerLineMap |
+
+        rulesToIntervalsMap := highlighter rulesToIntervalsMap.
+        rulesToIntervalsMap notNil ifTrue:[ 
+            annotationsPerLineMap := Dictionary new.
+            rulesToIntervalsMap keysAndValuesDo:[ :rule :intervals |
+                intervals do:[:interval | 
+                    | line annotation |
+
+                    line := codeView lineOfCharacterPosition: interval first.
+                    annotation := annotationsPerLineMap at: line ifAbsentPut:[ Tools::LintAnnotation new line: line ].
+                    annotation rule notNil ifTrue:[ 
+                        annotation rule isComposite 
+                            ifTrue: [ annotation rule addRule:rule "rules add: rule" ]
+                            ifFalse:[ annotation rule: (RBCompositeLintRule rules: (OrderedCollection with: (annotation rule) with: rule))]
+                    ] ifFalse:[ 
+                        annotation rule: rule
+                    ].
+                ].
+            ].
+            annotations := annotationsPerLineMap values sort:[ :a :b | a line < b line ].
+            annotationsSequenceNumber := highlighter sequenceNumber.
+        ]
+    ].
+    ^annotations
+
+    "Created: / 15-12-2014 / 15:29:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 19:00:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+syntaxHighlighter
+
+    ^highlighter
+
+    "Created: / 05-08-2011 / 10:59:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService methodsFor:'aspects'!
+
+rulesHolder
+    "return/create the 'rulesHolder' value holder (automatically generated)"
+
+    rulesHolder isNil ifTrue:[
+        rulesHolder := ValueHolder new.
+        rulesHolder addDependent:self.
+    ].
+    ^ rulesHolder
+!
+
+rulesHolder:something
+    "set the 'rulesHolder' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    rulesHolder notNil ifTrue:[
+        oldValue := rulesHolder value.
+        rulesHolder removeDependent:self.
+    ].
+    rulesHolder := something.
+    rulesHolder notNil ifTrue:[
+        rulesHolder addDependent:self.
+    ].
+    newValue := rulesHolder value.
+    oldValue ~~ newValue ifTrue:[
+        self update:#value with:newValue from:rulesHolder.
+    ].
+! !
+
+!SmalltalkLintService methodsFor:'change & update'!
+
+sourceChanged:force
+    | lang |
+
+    rules isNil ifTrue:[ ^ self ].
+    ((lang := codeView language) isNil or:[lang isSmalltalk not]) ifTrue:[ ^ self ].
+    rules resetResult.
+    annotations := nil.
+    super sourceChanged:force.
+
+    "Created: / 18-02-2012 / 22:50:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 19:00:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+update:something with:aParameter from:changedObject
+    "Invoked when an object that I depend upon sends a change notification."
+
+    changedObject == rulesHolder ifTrue:[
+        UserPreferences current smallSenseBackgroundLintEnabled ifTrue:[
+            | rulesHierarchical ruleList disabledRules |
+
+            "/xxxx
+            rulesHierarchical := rulesHolder value.
+            rulesHierarchical notNil ifTrue:[
+                disabledRules := SmalltalkChecker forceDisabledRules.
+                ruleList := rulesHierarchical flattened reject:[:each| disabledRules includes: each class name].
+                ruleList := ruleList collect:[ :e | e class new ].
+                rules := RBCompositeLintRule rules: ruleList.
+                highlighter rules: ruleList.
+                self process.
+            ].
+        ].
+        ^ self.
+    ].
+
+    super update:something with:aParameter from:changedObject
+
+    "Modified (format): / 16-10-2014 / 23:20:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService methodsFor:'event handling'!
+
+buttonPress:button x:x y:y in:view 
+    |lineNr|
+
+    rules isNil ifTrue:[
+        ^ false
+    ].
+    view == gutterView ifTrue:[
+        button == 1 ifTrue:[
+            lineNr := textView yVisibleToLineNr:y.
+            lineNr notNil ifTrue:[ 
+                ^ self showInfoWindowForLine: lineNr 
+            ].
+            ^ false.
+        ].
+    ].
+    ^ false
+
+    "Created: / 30-01-2012 / 21:04:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+viewRealized
+
+    | browser |
+
+    UserPreferences current smallSenseBackgroundLintEnabled ifFalse:[ ^ self ].
+
+    (browser := codeView browser) notNil ifTrue:[
+        browser navigationState canvasType ~~ #smallLintByRuleResultBrowserSpec ifTrue:[
+            self rulesHolder: (browser perform:#smalllintRulesOrDefaultHolder ifNotUnderstood:[browser smalllintRulesOrAllHolder])
+        ].
+    ].
+
+    "Created: / 23-01-2012 / 10:43:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-02-2013 / 22:43:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService methodsFor:'initialization'!
+
+initialize
+
+    super initialize.
+
+    highlighter := Tools::LintHighlighter new.
+
+    "Created: / 05-08-2011 / 11:53:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 03-12-2014 / 09:38:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService methodsFor:'private'!
+
+process
+    "(Re)starts the processing job. Should be called whenever a source 
+     must be (re)processed."
+
+    rules isNil ifTrue:[
+        ^self
+    ].
+
+    ^super process.
+
+    "Created: / 24-01-2012 / 12:43:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+process: delayed
+    "Do the real source processing. If delayed is true, actuall data update must
+     be done within the event queue using #pushUserEvent:...
+    "
+    |lang cls env oldCodeList oldCode |
+
+    rules isNil ifTrue:[ ^ self ].
+    codeView codeAspect ~~ #method ifTrue:[ ^ self ].
+    (lang := codeView language) isNil ifTrue: [ ^ self ].
+    lang isSmalltalk ifFalse: [ ^ self ]. 
+    done := false.
+    modified := false.
+
+    cls := codeView klass.
+        cls isNil ifTrue:[^ self ].    
+
+
+    Delay waitForMilliseconds: 200."Give user some time to write"
+
+    (cls notNil and:[cls isObsolete]) ifTrue:[
+        cls isMeta ifTrue:[
+            cls := (Smalltalk at:cls theNonMetaclass name) class
+        ] ifFalse:[
+            cls := Smalltalk at:cls name
+        ].
+    ].
+
+    "textView" modified ifFalse:[
+        oldCodeList := textView list copy.
+        oldCodeList isEmptyOrNil ifTrue: [ ^ self ].
+        "textView" modified ifFalse:[
+            oldCodeList isNil ifFalse:[
+                oldCode := oldCodeList asStringWithoutEmphasis.
+                oldCode isEmptyOrNil ifTrue:[ ^ self ].
+                "textView" modified ifFalse:[
+                    Screen currentScreenQuerySignal answer:codeView device
+                    do:[
+                        Error handle:[:ex |
+                            | errMsg |
+
+                            Debugging == true ifTrue:[
+                                Debugging := false.    
+                                ex pass.
+                            ].
+
+"/                            Transcript topView raiseDeiconified.
+"/                            Transcript showCR:'ParseError: ', ex description.
+                            errMsg := ex description asStringCollection first asString.
+                            self showInfo:(('Smalltalk Lint: ',errMsg) colorizeAllWith:Color red).
+                        ] do:[
+                            env := (SmallSense::SmalltalkUnacceptedMethodEnvironment onClass:cls methodSource: oldCode).
+                            SmalltalkChecker runRule: rules onEnvironment: env
+                        ].
+                        delayed ifTrue:[
+                            codeView sensor pushUserEvent:#rehighlight: for:self withArgument: true.
+                        ] ifFalse:[
+                            self rehighlight: true.
+                        ]
+                    ]
+                ]
+            ]
+        ]
+    ]
+
+    "Created: / 24-01-2012 / 12:44:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-10-2014 / 01:10:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+rehighlight: delayed
+    | service |
+
+    service := self service: SmallSense::CodeHighlightingService name.
+    service isNil ifTrue:[
+        service := self service: Tools::CodeHighlightingService name
+    ].
+    service notNil ifTrue:[
+        service sourceChanged: true.
+    ]
+
+    "Created: / 27-01-2012 / 17:06:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 15-12-2014 / 19:00:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+showInfoWindowForLine: lineNo
+    | ann |
+
+    ann := self annotationAtLine: lineNo.
+    ann isNil ifTrue:[ ^ false ].
+
+    codeView topView beMaster.
+
+    CriticsWindow new
+        rule: ann rule;
+        codeView: codeView;
+        allButOpen;
+        "/ openWindowAt: (Screen current pointerPosition - (20@20)).
+        openWindowAs:#popUp at: (Screen current pointerPosition - (20@20)).
+
+    ^true
+
+    "Created: / 30-01-2012 / 21:04:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService methodsFor:'redrawing'!
+
+drawLine:lineNo in:view atX:x y:y width:w height:h from:startCol to:endColOrNil with:fg and:bg 
+    "Called by both gutterView and textView (well, not yet) to
+     allow services to draw custom things on text view.
+     Ask JV what the args means if unsure (I'm lazy to document
+     them, now it is just an experiment...)"
+
+    | lang annotation |
+
+    "/ ((lang := codeView language) isNil or:[lang isSmalltalk not]) ifTrue:[ ^ self ].
+
+    UserPreferences current smallSenseBackgroundLintEnabled ifFalse:[ ^ self ].
+
+    annotation :=  self annotationAtLine: lineNo.
+    annotation notNil ifTrue:[
+        self drawAnnotationIcon: (ToolbarIconLibrary smalllintWarning16x16)
+                atX: x y: y  width: w height: h.
+    ].
+
+    "Created: / 30-01-2012 / 15:11:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 15:28:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService methodsFor:'registering'!
+
+unregister
+    super unregister.
+    rulesHolder removeDependent: self.
+
+    "Created: / 14-10-2014 / 22:40:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkLintService class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/smallsense/SmallSense__SmalltalkLintService.st,v 1.2 2015-01-31 01:00:16 cg Exp $'
+!
+
+version_CVS
+    ^ '$Path: stx/goodies/smallsense/SmallSense__SmalltalkLintService.st, Version: 1.0, User: cg, Time: 2015-01-31T02:00:40.102+01$'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id: SmallSense__SmalltalkLintService.st,v 1.2 2015-01-31 01:00:16 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkParseNodeFinder.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,136 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SmalltalkParseNodeVisitor subclass:#SmalltalkParseNodeFinder
+	instanceVariableNames:'position match previous'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk'
+!
+
+!SmalltalkParseNodeFinder class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkParseNodeFinder methodsFor:'finding'!
+
+findNodeIn: source tree: tree comments: comments line: line column: col
+
+    | sourceS |
+    sourceS := source readStream.
+    line - 1 timesRepeat:[
+        (sourceS nextLine) isNil ifTrue:[
+            "No such line"                                
+            ^nil
+        ].        
+    ].
+    ^self findNodeIn: source tree: tree comments: comments position: sourceS position + col
+
+    "Created: / 29-01-2014 / 10:20:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+findNodeIn:source tree:tree comments:comments position:pos 
+    | i s e |
+
+    position := pos - 1.
+    i := 1.
+    [
+        i < comments size and:[ (s := comments at:i) notNil ]
+    ] whileTrue:[
+        e := "s + "(comments at:i + 1)" - 1".
+        (pos between:s and:e) ifTrue:[
+            ^ nil -> pos.
+        ].
+        i := i + 2.
+    ].
+    (s notNil and:[ source size == e ]) ifTrue:[ 
+        ^ nil -> pos.     
+    ].
+    self visit:tree.
+    ^ (match ? previous) -> pos.
+
+    "Created: / 29-01-2014 / 10:20:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 17-06-2014 / 16:04:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParseNodeFinder methodsFor:'visiting'!
+
+visit:anObject 
+
+    anObject isNil ifTrue:[^self].
+
+    (anObject endPosition notNil and:[position > anObject endPosition]) ifTrue:[
+        previous := anObject.
+        anObject acceptVisitor: self.
+        ^self.
+    ].
+
+    (anObject startPosition notNil 
+        and:[anObject endPosition notNil 
+        and:[position between: anObject startPosition and: anObject endPosition]]) ifTrue:[
+        match := anObject.
+    ].
+    anObject acceptVisitor: self.
+
+    "Created: / 26-11-2011 / 15:40:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-09-2013 / 11:15:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitStatementNode:anObject 
+
+    self visit: anObject expression.
+    self visit: anObject nextStatement.
+
+    "Modified: / 25-07-2011 / 22:34:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Created: / 26-11-2011 / 15:40:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParseNodeFinder class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkParseNodeVisitor.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,253 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#SmalltalkParseNodeVisitor
+	instanceVariableNames:'class'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk'
+!
+
+!SmalltalkParseNodeVisitor class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    An abstract parse tree visitor. Copied from libcomp
+    as ParseNodeVisitor is autoloaded and we need smallsense
+    to be fully compiled.
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!SmalltalkParseNodeVisitor class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!SmalltalkParseNodeVisitor class methodsFor:'processing'!
+
+process: tree in: class
+
+    ^self new process: tree in: class
+
+    "Created: / 26-11-2011 / 13:48:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParseNodeVisitor methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    "/ please change as required (and remove this comment)
+
+    "/ super initialize.   -- commented since inherited method does nothing
+! !
+
+!SmalltalkParseNodeVisitor methodsFor:'processing'!
+
+process: tree in: cls
+
+    class := cls.
+    self visit: tree
+
+    "Created: / 26-11-2011 / 13:48:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParseNodeVisitor methodsFor:'visiting'!
+
+visit:anObject 
+
+    | stmt |
+
+    anObject isNil ifTrue:[ ^ self ].
+
+    ^anObject isStatementNode ifTrue:[
+        stmt := anObject.
+        [ stmt notNil and:[stmt isStatementNode ] ] whileTrue:[
+            stmt acceptVisitor:self.
+            stmt := stmt nextStatement.
+        ].
+        stmt notNil ifTrue:[
+            stmt acceptVisitor: self.
+        ].
+    ] ifFalse:[
+        anObject acceptVisitor: self.
+    ]
+
+    "Modified: / 26-02-2014 / 22:45:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitAssignmentNode:anObject
+
+    self visit: anObject variable.
+    self visit: anObject expression.
+
+    "Modified: / 26-11-2011 / 13:20:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitBinaryNode:anObject 
+
+    ^self visitMessageNode: anObject
+
+    "Modified: / 25-07-2011 / 22:30:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitBlockNode:anObject 
+
+    anObject statements ifNotNil:[
+        self visit: anObject statements
+    ].
+
+    "Modified: / 25-07-2011 / 22:45:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitCascadeNode:anObject 
+
+    self visitMessageNode: anObject.
+
+    "Modified: / 25-07-2011 / 22:37:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitConstantNode:anObject
+
+    "Modified: / 25-07-2011 / 22:41:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitECompletionConstantNode:anObject 
+    "dispatched back from the visited eCompletionConstantNode-object (visitor pattern)"
+
+    "fall back to general object-case - please change as required"
+
+    ^ self visitObject:anObject
+!
+
+visitMessageNode:anObject 
+
+    self visit: anObject receiver.
+    anObject arguments do:[:arg|
+        self visit: arg.
+    ]
+
+    "Modified: / 25-07-2011 / 22:37:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitObject:anObject 
+    "dispatched back from the visited objects (visitor pattern)"
+
+    "general fallBack - please change as required"
+
+    self halt:'not yet implemented'
+!
+
+visitParseErrorNode:anObject
+    anObject children notNil ifTrue:[
+        anObject children do:[:each|self visit: each].
+    ]
+
+    "Modified: / 15-08-2013 / 12:34:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitPrimitiveNode:anObject
+
+    "Modified: / 25-07-2011 / 22:38:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitReturnNode:anObject 
+
+    self visitStatementNode: anObject
+
+    "Modified: / 25-07-2011 / 22:34:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitSelfNode:anObject
+
+    "Modified: / 25-07-2011 / 22:38:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitStatementNode:anObject 
+
+    self visit: anObject expression.
+
+    "Modified: / 25-07-2011 / 22:34:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitSuperNode:anObject
+
+    "Modified: / 25-07-2011 / 22:38:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitUnaryNode:anObject 
+
+    self visitMessageNode: anObject
+
+    "Modified: / 25-07-2011 / 22:38:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+visitVariableNode:anObject
+
+    "Modified: / 25-07-2011 / 22:38:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParseNodeVisitor class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkParser.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,641 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SyntaxHighlighter subclass:#SmalltalkParser
+	instanceVariableNames:'errorRecovery error commentPositions commentIndex'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk'
+!
+
+!SmalltalkParser class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkParser methodsFor:'accessing'!
+
+commentPositions
+    ^ commentPositions
+! !
+
+!SmalltalkParser methodsFor:'error handling'!
+
+parseError:message position:startPos to:endPos
+
+    error := ParseErrorNode new 
+                errorString: message;
+                errorToken:  (token notNil ifTrue:[token asString] ifFalse:[nil]);
+                startPosition: startPos endPosition: endPos.
+    ^error
+
+    "Created: / 27-11-2011 / 09:35:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-08-2013 / 12:21:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+syntaxError:message position:startPos to:endPos
+
+    ^self parseError:message position:startPos to:endPos
+
+    "Created: / 27-11-2011 / 09:45:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser methodsFor:'initialization'!
+
+initialize
+    super initialize.
+    errorRecovery := true.
+    commentPositions := Array new: 16.
+    commentIndex := -1.
+    saveComments := true.
+
+    "Created: / 19-09-2013 / 11:25:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-01-2014 / 10:38:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser methodsFor:'parsing'!
+
+blockStatementList
+    "parse a blocks statementlist; return a node-tree, nil or #Error"
+
+    |thisStatement prevStatement firstStatement eMsg blockStart lastErrorPosition |
+
+    blockStart := tokenPosition.
+
+    (tokenType == $] ) ifTrue:[^ nil].
+
+    thisStatement := self statement.
+    (thisStatement == #Error) ifTrue:[^ #Error].
+    firstStatement := thisStatement.
+    [tokenType == $] ] whileFalse:[
+        (tokenType == $.) ifFalse:[
+            (tokenType == #EOF) ifTrue:[
+                | errnode |
+                errnode := self syntaxError:'missing '']'' in block' position:blockStart to:(source position + 1).
+                errnode children: (Array with: firstStatement).
+                ^errnode
+            ].
+
+            (tokenType == $) ) ifTrue:[
+                eMsg := 'missing '']'' or bad '')'' in block'
+            ] ifFalse:[
+                eMsg := 'missing ''.'' between statements (i.e. ''' , tokenType printString , '''-token unexpected)'
+            ].
+
+            lastErrorPosition == tokenPosition ifTrue:[
+                "/ Failed to recover, still on the same token, give up.
+                ^ error
+            ].
+            lastErrorPosition := tokenPosition.
+
+            "/ Report error...
+            self syntaxError:eMsg position:thisStatement startPosition to:tokenPosition.
+            "/ ...an try to recover...
+
+            " Situation 1: ================== 
+                number isEven ifTrue:[
+                    inst
+                    number := number + 1.
+                ]
+            In this case, the `number` token is already consumed, leaving 
+            UnaryNode with selector #number as an expression of last statement. 
+            The current token is #:=. Try to recover by setting stream position
+            just past of `inst` token"
+            (token == #':=' 
+                and:[thisStatement expression isMessage 
+                    and:[thisStatement expression numArgs == 0
+                        and:[thisStatement expression receiver endPosition notNil]]]) ifTrue:[
+                            source position: thisStatement expression receiver endPosition.
+                            thisStatement expression: thisStatement expression receiver.
+                            self nextToken.
+                        ]
+        ] ifTrue:[
+            self nextToken.
+        ].
+
+        prevStatement := thisStatement.
+
+        tokenType == $] ifTrue:[
+            "
+            *** I had a warning here (since it was not defined
+            *** in the blue-book; but PD-code contains a lot of
+            *** code with periods at the end so that the warnings
+            *** became annoying
+
+            self warning:'period after last statement in block'.
+            "
+            self markBracketAt:tokenPosition.
+            ^ self statementListRewriteHookFor:firstStatement
+        ].
+        thisStatement := self statement.
+        (thisStatement == #Error) ifTrue:[^ #Error].
+        prevStatement nextStatement:thisStatement
+    ].
+    self markBracketAt:tokenPosition.
+    ^ self statementListRewriteHookFor:firstStatement
+
+    "Created: / 15-08-2013 / 12:16:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 26-08-2013 / 11:33:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parseExpressionWithSelf:anObject notifying:someOne ignoreErrors:ignoreErrors ignoreWarnings:ignoreWarnings inNameSpace:aNameSpaceOrNil
+
+    |tree token|
+
+    aNameSpaceOrNil notNil ifTrue:[
+        self currentNameSpace:aNameSpaceOrNil
+    ].
+    self setSelf:anObject.
+    self notifying:someOne.
+    self ignoreErrors:ignoreErrors.
+    self ignoreWarnings:ignoreWarnings.
+    token := self nextToken.
+    (token == $^) ifTrue:[
+        self nextToken.
+    ].
+    (token == #EOF) ifTrue:[
+        ^ nil
+    ].
+    "/tree := self expression.
+    tree := self statementList.    
+    (self errorFlag or:[tree == #Error]) ifTrue:[^ #Error].
+    ^ tree
+
+    "Created: / 14-12-1999 / 15:11:37 / cg"
+    "Created: / 09-07-2011 / 22:23:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parseMethod:aString in:aClass ignoreErrors:ignoreErrors ignoreWarnings:ignoreWarnings
+    "parse a method in a given class.
+     Return a parser (if ok), nil (empty) or #Error (syntax).
+     The parser can be queried for selector, receiver, args, locals,
+     used selectors, modified instvars, referenced classvars etc.
+     The noErrors and noWarnings arguments specify if error and warning
+     messages should be sent to the Transcript or suppressed."
+
+    self sourceText: aString copy asText.
+    ^ super parseMethod:aString in:aClass ignoreErrors:ignoreErrors ignoreWarnings:ignoreWarnings
+
+    "Created: / 03-02-2014 / 16:15:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+statement
+    "parse a statement; return a node-tree or #Error.
+
+     statement ::= '^' expression
+                   | PRIMITIVECODE
+                   | expression
+    "
+
+    |expr node lnr code pos|
+
+    pos := tokenPosition.
+
+    (tokenType == $^) ifTrue:[
+        ^ self returnStatement
+    ].
+
+    (tokenType == #Primitive) ifTrue:[
+        code := tokenValue.
+        node := PrimitiveNode code:code.
+        node startPosition: tokenPosition endPosition: source position + 1.
+        self nextToken.
+        node isOptional ifFalse:[
+            hasNonOptionalPrimitiveCode := true
+        ].
+        hasPrimitiveCode := true.
+        ^ node
+    ].
+
+    (tokenType == #EOF) ifTrue:[
+        currentBlock notNil ifTrue:[
+            self syntaxError:'missing '']'' at end of block'.
+            errorRecovery ifTrue:[
+                tokenType := $].
+                ^ error.
+            ].
+        ] ifFalse:[
+            self syntaxError:'period after last statement'.
+            errorRecovery ifTrue:[
+                tokenType := $..
+                ^ error.
+            ].  
+        ].
+        ^ #Error
+    ].
+
+    (tokenType == $.) ifTrue:[
+        (parserFlags allowEmptyStatements
+        or:[parserFlags allowSqueakExtensions == true]) ifTrue:[
+            "/ allow empty statement
+            self warnAboutEmptyStatement.
+            node := StatementNode expression:nil.
+            node startPosition:pos.
+            ^ node
+        ].
+    ].
+
+    lnr := tokenLineNr.
+
+    expr := self expression.
+    (expr == #Error) ifTrue:[^ #Error].
+
+"/    classToCompileFor notNil ifTrue:[
+"/        currentBlock isNil ifTrue:[
+"/            expr isPrimary ifTrue:[
+"/                self warning:'useless computation - missing ^ ?'
+"/            ]
+"/        ]
+"/    ].
+
+    node := StatementNode expression:expr.
+    parserFlags fullLineNumberInfo ifTrue:[node lineNumber:lnr].
+    node startPosition:pos.
+    ^ node
+
+    "Created: / 19-09-2013 / 11:32:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser methodsFor:'parsing-expressions'!
+
+keywordExpression
+    "parse a keyword-expression; return a node-tree, nil or #Error.
+
+     keywordExpression ::= binaryexpression
+                           | { KEYWORD-PART binaryExpression }
+    "
+
+    |receiver expr|
+
+    receiver := self binaryExpression.
+    (receiver == #Error) ifTrue:[^ #Error].
+    (tokenType == #EOF) ifTrue:[^ receiver].
+    tokenType == $] ifTrue:[^ receiver].
+    tokenType == $) ifTrue:[^ receiver].
+    expr := self keywordExpressionFor:receiver.
+
+    "/ expr could be an assignment as well, here
+    (ignoreWarnings or:[ignoreErrors]) ifFalse:[
+        "/ for a better error message, in case of a missing period in the previous message,
+        "/    <expr> <missing period> foo := ...
+        "/ would be parsed as unary message foo; detect this here, instead of high up in the calling hierarchy,
+        "/ where it is difficult to provide a reasonable error message
+        tokenType == #':=' ifTrue:[
+            | positionOfPeriod exprLast exprLastParent |
+
+            "/ Find the very last unary send node, Consider:
+            "/    x := 2
+            "/    y := false
+            "/ 
+            "/    x := 2 between: 0 and: 10
+            "/    y := false  
+            "/ 
+            "/    x := 2 between: 0 and: self max
+            "/    y := false  
+
+            exprLastParent := nil.
+            exprLast := expr.
+            [ exprLast isMessage and: [ exprLast isUnaryMessage not ] ] whileTrue:[
+                exprLastParent := exprLast.
+                exprLast := exprLast args last.
+            ].
+            (exprLast isMessage and: [ exprLast isUnaryMessage ] ) ifTrue:[
+                positionOfPeriod := exprLast receiver positionToInsertPeriodForStatementSeparation
+            ].
+            positionOfPeriod notNil ifTrue:[
+                "/Try to recover
+                "/ Strip the last unary message whose selector is actually a variable name..."
+                exprLastParent notNil ifTrue:[
+                    exprLastParent args at: exprLastParent args size put: exprLast receiver.
+                ] ifFalse:[
+                    "/ no nesting, the expr itself is errorneouts...    
+                     expr := expr receiver.
+                ].
+                expr := ParseErrorNode new
+                        startPosition:expr startPosition endPosition: positionOfPeriod - 1;
+                        errorString: ('":=" unexpected. Probably missing "." in previous expression.');
+                        children: (Array with: expr);
+                        yourself.        
+                source position: positionOfPeriod.
+                tokenType := $.
+            ]
+        ].
+    ].
+
+    ^ expr
+
+    "Created: / 16-09-2013 / 17:23:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-09-2013 / 11:47:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+primary
+    | nodeOrError |
+
+    nodeOrError := super primary.
+    ^ (nodeOrError == #Error and:[error notNil]) ifTrue:[
+        error
+    ] ifFalse:[
+        nodeOrError 
+    ]
+
+    "Created: / 19-08-2013 / 14:07:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+primary_expression
+    "parse a parentized expression primary; return a node-tree, or raise an Error."
+
+    |pos val eMsg|
+
+    pos := tokenPosition.
+
+    self nextToken.
+    val := self expression.
+    (val == #Error) ifTrue:[^ #Error].
+    (tokenType == $) ) ifFalse:[
+        | errnode |
+        tokenType isCharacter ifTrue:[
+            eMsg := 'missing '')'' (i.e. ''' , tokenType asString , ''' unexpected)'.
+        ] ifFalse:[
+            eMsg := 'missing '')'''.
+        ].
+        errnode := self syntaxError:eMsg withCRs position:pos to:tokenPosition.
+        errnode children: (Array with: val).
+        ^ errnode
+    ].
+    self markParenthesisAt:tokenPosition.
+    parenthesisLevel := parenthesisLevel - 1.
+    self nextToken.
+    (self noAssignmentAllowed:'Invalid assignment to an expression' at:pos) ifFalse:[
+        ^ #Error
+    ].
+    val parenthesized:true.
+    ^ val
+
+    "Created: / 15-08-2013 / 15:23:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser methodsFor:'parsing-tweaks'!
+
+_blockStatementList
+    "parse a blocks statementlist; return a node-tree, nil or #Error"
+    
+    |thisStatement prevStatement firstStatement eMsg blockStart|
+
+    blockStart := tokenPosition.
+    (tokenType == $]) ifTrue:[
+        ^ nil
+    ].          
+    thisStatement := self statement.
+    (thisStatement == #Error) ifTrue:[
+        ^ #Error
+    ].
+    firstStatement := thisStatement.
+    [
+        tokenType == $] or:[ tokenType == #EOF ]
+    ] whileFalse:[
+        (tokenType == $.) ifFalse:[   
+            (tokenType == #EOF) ifTrue:[
+                "    self syntaxError:'missing '']'' in block' position:blockStart to:(source position1Based).
+                    ^ #Error."
+            ].
+            (tokenType == $)) ifTrue:[
+                eMsg := 'missing '']'' or bad '')'' in block'
+            ] ifFalse:[
+                eMsg := 'missing ''.'' between statements (i.e. ''' 
+                            , tokenType printString , '''-token unexpected)'
+            ].          
+             "self syntaxError:eMsg position:blockStart to:tokenPosition.
+             ^ #Error"
+        ].
+
+        prevStatement := thisStatement.    
+        (eMsg isNil ) ifTrue:[              
+            self nextToken.
+        ].
+        tokenType == $] ifTrue:[
+            "
+             *** I had a warning here (since it was not defined
+             *** in the blue-book; but PD-code contains a lot of
+             *** code with periods at the end so that the warnings
+             *** became annoying
+
+             self warning:'period after last statement in block'."
+            self markBracketAt:tokenPosition.
+            ^ firstStatement
+        ].
+        thisStatement := self statement.
+        (thisStatement == #Error) ifTrue:[
+            ^ #Error
+        ].
+        prevStatement nextStatement:thisStatement.
+        (eMsg notNil) ifTrue:[
+            self nextToken.
+        ].
+        eMsg := nil.
+    ].
+    self markBracketAt:tokenPosition.
+    ^ self statementListRewriteHookFor:firstStatement
+
+    "Created: / 05-08-2013 / 14:56:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+_primary
+    "parse a primary-expression; return a node-tree, nil or #Error.
+     This also cares for namespace-access-pathes."
+    
+    | node |
+    node := super primary.
+    "/If an error occured, return the error node"
+    node == #Error ifTrue:[
+        self assert: error notNil description: 'Parse error occured but no error node.'.
+        node := error. error := nil.
+    ].
+    ^node
+
+    "Created: / 05-08-2013 / 14:56:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+_statementList
+    "parse a statementlist; return a node-tree, nil or #Error.
+     Statements must be separated by periods.
+
+     statementList ::= <statement>
+                       | <statementList> . <statement>"
+    
+    |thisStatement prevStatement firstStatement periodPos prevExpr|
+
+    thisStatement := self statement.
+    (thisStatement == #Error) ifTrue:[
+        self breakPoint: #jv.            
+        ^ #Error
+    ].
+    firstStatement := thisStatement.
+    [ tokenType == #EOF ] whileFalse:[
+        prevExpr := thisStatement expression.
+        (prevExpr notNil 
+            and:[ prevExpr isMessage and:[ thisStatement isReturnNode not ] ]) 
+                ifTrue:[
+                    (#( #'=' #'==' ) includes:prevExpr selector) ifTrue:[
+                        self 
+                            warning:'useless computation - mistyped assignment (i.e. did you mean '':='') ?'
+                            position:prevExpr selectorPosition
+                    ].
+                ].
+        periodPos := tokenPosition.
+
+        (tokenType == $. or:[ firstStatement = thisStatement and:[firstStatement expression isErrorNode] ]) ifTrue:[    
+            self nextToken.
+        ].
+        tokenType == $. ifTrue:[
+            self emptyStatement.
+        ].
+        (tokenType == $]) ifTrue:[
+            currentBlock isNil ifTrue:[
+                
+            ] ifFalse:[
+                ^ self statementListRewriteHookFor:firstStatement
+            ].
+        ].
+        (tokenType == #EOF) ifTrue:[
+            currentBlock notNil ifTrue:[
+                "self parseError:''']'' expected (block nesting error)'."
+            ] ifFalse:[
+                ^ self statementListRewriteHookFor:firstStatement
+            ].
+        ].
+        prevStatement := thisStatement.
+        prevStatement isReturnNode ifTrue:[
+            self warning:'statements after return' position:tokenPosition
+        ].
+        thisStatement := self statement.
+        (thisStatement == #Error) ifTrue:[
+            self breakPoint: #jv.           
+            ^ #Error
+        ].
+        (thisStatement expression isNil or:[thisStatement expression isErrorNode]) ifTrue:[
+            self nextToken.
+        ].
+
+        prevStatement nextStatement:thisStatement
+    ].
+    ^ self statementListRewriteHookFor:firstStatement
+
+    "Created: / 05-08-2013 / 14:56:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser methodsFor:'private'!
+
+findNameSpaceWith:varName
+    | ns |
+
+    "The super #findNameSpaceWith: checks whether the the global named 'varName' exists,
+     if not, returns the current namespace which is then prepended to 'varName'.
+
+     Here we have to deal with uncomplete global names, so trick the caller by returning
+     nil if the partially typed global name starts with current namespace prefix."
+
+    classToCompileFor notNil ifTrue:[
+        ns := classToCompileFor topNameSpace.
+        (varName = ns name) ifTrue:[
+            ^ nil
+        ]
+    ].
+
+    ^ super findNameSpaceWith:varName
+
+    "Created: / 28-07-2013 / 13:49:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 29-01-2014 / 10:04:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser methodsFor:'syntax coloring'!
+
+markBracketAt:pos
+
+    pos > sourceText size ifTrue:[^self].
+    super markBracketAt:pos
+
+    "Created: / 03-04-2011 / 22:39:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-02-2014 / 23:06:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+markFrom:pos1 to:pos2 withEmphasis:fontEmp color:clrIn
+
+    sourceText isNil ifTrue:[^self].
+    super markFrom:pos1 to:pos2 withEmphasis:fontEmp color:clrIn
+
+    "Created: / 03-04-2011 / 22:24:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+markFrom:pos1 to:pos2 withEmphasis:fontEmp color:fgClr1 ifNil:fgClr2 backgroundColor:bgClr
+
+    sourceText isNil ifTrue:[^self].
+    super markFrom:pos1 to:pos2 withEmphasis:fontEmp color:fgClr1 ifNil:fgClr2 backgroundColor:bgClr
+
+    "Created: / 14-02-2012 / 11:08:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser methodsFor:'syntax detection'!
+
+markCommentFrom:pos1 to:pos2
+    commentIndex := commentIndex + 2.
+    (commentPositions size) < (commentIndex + 1) ifTrue:[ 
+        | newPositions |
+
+        newPositions := Array new: commentPositions size + 16.
+        newPositions replaceFrom: 1 with: commentPositions.
+        commentPositions := newPositions.
+    ].
+    commentPositions at: commentIndex put: pos1.               
+    commentPositions at: commentIndex + 1 put: pos2.
+
+    "Created: / 31-03-2014 / 22:28:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkParser class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkParserTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,1143 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+TestCase subclass:#SmalltalkParserTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests-Obsolete'
+!
+
+!SmalltalkParserTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkParserTests methodsFor:'parseTests'!
+
+test1
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |u w b c d tokenValue val uu bb cc dd |
+                   u := 3.
+                    b:=u.
+                    c:=u floor.
+                    d floor:u.
+                    d floor:3 b:u.
+                    self rememberSymbolUsed:tokenValue.
+                    array:=#( 3 4 5 6 ).
+                    val := ConstantNode type:tokenType value:tokenValue.
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+                    bb:=uu.
+                    cc:=uu floor.
+                    dd floor:uu.
+                    dd floor:3 b:uu.
+                    ].
+                    dd do:[:w|w seduce.
+                    ].
+                    ^self.
+                    '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+
+    "Created: / 21-12-2010 / 23:07:13 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 22-02-2011 / 12:35:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test10
+    |collector|
+
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3.
+                    b:=u.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree nextStatement nextStatement) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression expression) isConstant.
+    self assert:(collector tree nextStatement expression) isAssignment.
+    self assert:(collector tree nextStatement expression variable) isVariable.
+    self 
+        assert:(collector tree nextStatement expression expression) isVariable.
+
+    "Created: / 15-02-2011 / 15:23:50 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 16:49:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test11
+    |collector|
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3
+                    b:=u.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree nextStatement nextStatement nextStatement) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression variable name= 'u').
+    self assert:(collector tree expression expression) isUnaryMessage.
+    self assert:(collector tree expression expression receiver) isConstant.
+    self assert:(collector tree expression expression receiver value=3) .
+    self assert:(collector tree expression expression selector asString)='b'.
+    self assert:(collector tree expression expression args isNil ).
+    self assert:(collector tree nextStatement expression) isErrorNode.
+    self assert:(collector tree nextStatement expression errorToken)= ':='.
+    self assert:(collector tree nextStatement nextStatement expression) isVariable.
+    self assert:(collector tree nextStatement nextStatement expression name)='u'.
+
+    "Created: / 15-02-2011 / 15:24:01 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 16:58:56 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test11a
+    |collector|
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3
+                    b:=u.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree nextStatement nextStatement) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression variable name= 'u').
+
+    self assert:(collector tree expression expression) isErrorNode.
+    self assert:(collector tree expression expression children first receiver) isConstant.
+    self assert:(collector tree expression expression children first receiver) value =3 .
+
+    self assert:(collector tree nextStatement expression) isAssignment.
+    self assert:(collector tree nextStatement expression) variable name = 'b'.
+    self assert:(collector tree nextStatement expression) expression isVariable.
+    self assert:(collector tree nextStatement expression) expression name = 'u'.
+
+    "Created: / 16-09-2013 / 23:16:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test11b
+    |collector|
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3 between: 1 and: 10
+                    b:=u.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree nextStatement nextStatement) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression variable name= 'u').
+
+    self assert:(collector tree expression expression) isErrorNode.
+    self assert:(collector tree expression expression children first receiver) isConstant.
+    self assert:(collector tree expression expression children first receiver) value =3 .
+
+    self assert:(collector tree nextStatement expression) isAssignment.
+    self assert:(collector tree nextStatement expression) variable name = 'b'.
+    self assert:(collector tree nextStatement expression) expression isVariable.
+    self assert:(collector tree nextStatement expression) expression name = 'u'.
+
+    "Created: / 16-09-2013 / 23:16:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test11c
+    |collector|
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3 between: 1 and: 10 + 10
+                    b:=u.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree nextStatement nextStatement) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression variable name= 'u').
+
+    self assert:(collector tree expression expression) isErrorNode.
+    self assert:(collector tree expression expression children first receiver) isConstant.
+    self assert:(collector tree expression expression children first receiver) value =3 .
+
+    self assert:(collector tree nextStatement expression) isAssignment.
+    self assert:(collector tree nextStatement expression) variable name = 'b'.
+    self assert:(collector tree nextStatement expression) expression isVariable.
+    self assert:(collector tree nextStatement expression) expression name = 'u'.
+
+    "Created: / 16-09-2013 / 23:16:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test12
+    |collector|
+    collector := self 
+                doForSource:'  
+                    | b|
+                     : 3
+                    '.
+self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree nextStatement  nextStatement) isNil.
+    self assert:(collector tree expression) isErrorNode.
+    self assert:(collector tree expression errorToken =':').
+    self assert:(collector tree nextStatement expression) isConstant.
+    self assert:(collector tree nextStatement expression value=3).
+
+    "Created: / 15-02-2011 / 15:25:36 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 17:08:54 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test13
+    |collector|
+
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3
+                    :=u.
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self 
+        assert:(collector tree nextStatement nextStatement nextStatement) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression variable name = 'u').
+    self assert:(collector tree expression expression) isConstant.
+    self assert:(collector tree expression expression value =3).
+    self assert:(collector tree nextStatement expression) isErrorNode.
+    self assert:(collector tree nextStatement expression errorToken) = ':='.
+    self 
+        assert:(collector tree nextStatement nextStatement expression) isVariable.
+    self 
+        assert:(collector tree nextStatement nextStatement expression name) = 'u'.
+
+    "Created: / 15-02-2011 / 16:48:11 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 17-03-2011 / 17:21:48 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test14
+    |collector|
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3
+                    :u.
+                    '.
+ self assert:collector notNil.
+    self assert:collector tree notNil.
+    self 
+        assert:(collector tree nextStatement nextStatement nextStatement) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression variable name = 'u').
+    self assert:(collector tree expression expression) isConstant.
+    self assert:(collector tree expression expression value =3).
+    self assert:(collector tree nextStatement expression) isErrorNode.
+    self assert:(collector tree nextStatement expression errorToken) = ':'.
+    self 
+        assert:(collector tree nextStatement nextStatement expression) isVariable.
+    self 
+        assert:(collector tree nextStatement nextStatement expression name) = 'u'.
+
+    "Created: / 15-02-2011 / 17:03:42 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 19:52:39 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test15
+    |collector|
+    collector := self 
+                doForSource:'  
+                    | b|
+                    u := 3
+                    =u.
+                    '.
+ self assert:collector notNil.
+    self assert:collector tree notNil.
+    self 
+        assert:(collector tree nextStatement ) isNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression variable name = 'u').
+    self assert:(collector tree expression expression) isBinaryMessage.
+    self assert:(collector tree expression expression receiver value =3).
+    self assert:(collector tree expression expression receiver ) isConstant.
+    self assert:(collector tree expression expression selector )= #=.
+    self assert:(collector tree expression expression args size=1 ).
+    self assert:(collector tree expression expression arg ) isVariable.    
+    self assert:(collector tree expression expression arg name='u' ).
+
+    "Created: / 15-02-2011 / 17:04:33 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 19:56:28 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test19
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |b c|
+                   u := 3 u:=
+                    c u floor.
+                    '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isAssignment.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement expression isUnaryMessage.
+
+    "Created: / 15-02-2011 / 18:15:51 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:00:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test2
+
+    |collector|
+    collector := self 
+                doForSource:'
+                    u :'.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:(collector tree expression name ='u').
+self assert:(collector tree expression) isVariable.
+self assert:(collector tree nextStatement expression isErrorNode).
+self assert: collector tree nextStatement expression errorToken=':'.
+
+    "Created: / 09-02-2011 / 20:54:42 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 15:04:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test24
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |u w|
+                   self :                  '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isSelf.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':'.
+
+    "Created: / 15-02-2011 / 18:37:23 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:02:46 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test25
+    |collector|
+"    collector := self 
+                doForSource:'  
+                    |u w|
+                   self :=5                  '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isSelf.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement expression isConstant."
+
+    "Created: / 15-02-2011 / 18:37:56 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 28-02-2011 / 17:28:20 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test26
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |u w|
+                   false :=5                  '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isConstant.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement expression isConstant.
+
+    "Created: / 15-02-2011 / 19:50:17 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:05:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test27
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |u w|
+                   nil :=5                  '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isConstant.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement expression isConstant.
+
+    "Created: / 15-02-2011 / 19:51:02 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:05:32 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test28
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |d w tokenValue|
+                   d floor:3 b:u
+                    self rememberSymbolUsed:tokenValue.                '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+
+    "Created: / 15-02-2011 / 19:52:23 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:06:33 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test29
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |d u w|
+                   d floor:3 b:u
+                    self                 '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+
+    "Created: / 15-02-2011 / 19:53:15 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:06:46 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test3
+    |collector|
+
+    collector := self doForSource:'
+                    u ='.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression) isBinaryMessage.
+    self assert:(collector tree expression receiver name = 'u').
+    self assert:(collector tree expression receiver) isVariable.
+    self assert:(collector tree expression selector) == #=.
+    self assert:(collector tree expression args size) = 1.
+    self assert:(collector tree expression arg) isErrorNode.
+    self assert:(collector tree expression arg errorToken = 'EOF').
+
+    "Created: / 11-02-2011 / 15:32:58 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 15:20:22 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test30
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |array |
+                  self rememberSymbolUsed:tokenValue
+                    array:=#( 3 4 5 6 ).           '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+
+    "Created: / 15-02-2011 / 19:54:10 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test31
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |array tokenValue|
+                  self rememberSymbolUsed:tokenValue
+                    array:=( 3 4 5 6 ).           '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isMessage.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement  expression isUnaryMessage.
+
+    "Created: / 16-02-2011 / 15:51:47 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:15:19 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test32
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |uu w|
+                    [u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+
+                    ].
+
+                    '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+
+    "Created: / 16-02-2011 / 15:54:07 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test33
+    |collector|
+
+    collector := self 
+                doForSource:'  
+                    |uu w|
+                    u== #Symbol or:[u=3]]ifTrue:[
+                    uu := 4.
+
+                    ].
+
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:collector tree expression isMessage.
+    self assert:collector tree expression receiver isBinaryMessage.
+    self assert:collector tree expression receiver receiver isVariable.
+    self assert:collector tree expression receiver receiver name = 'u'.
+    self assert:collector tree expression receiver selector = #'=='.
+    self assert:collector tree expression receiver args size = 1.
+    self assert:collector tree expression receiver arg isConstant.
+    self assert:collector tree expression receiver arg value = #Symbol.
+    self assert:collector tree expression selector = #or:.
+    self assert:collector tree expression args size = 1.
+    self assert:collector tree expression arg1 isBlock.
+    self assert:collector tree expression arg1 statements expression 
+                isBinaryMessage.
+    self assert:collector tree nextStatement expression isErrorNode.
+    self assert:collector tree nextStatement expression errorToken = ']'.
+    self 
+        assert:collector tree nextStatement nextStatement expression isMessage.
+    self 
+        assert:collector tree nextStatement nextStatement expression receiver 
+                isErrorNode.
+    self 
+        assert:collector tree nextStatement nextStatement expression receiver 
+                errorToken = 'Keyword'.
+    self 
+        assert:collector tree nextStatement nextStatement expression selector 
+                = #ifTrue:.
+    self 
+        assert:collector tree nextStatement nextStatement expression args size = 1.
+    self 
+        assert:collector tree nextStatement nextStatement expression arg1 
+                statements expression 
+                isAssignment.
+
+    "Created: / 16-02-2011 / 15:55:49 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:52:03 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test34
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |array |
+                  self rememberSymbolUsed:tokenValue
+                    array:=#( 3 4 5 6 .           '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isMessage.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement  expression isConstant.
+
+    "Created: / 16-02-2011 / 16:09:35 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:16:54 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test35
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |uu w|
+                    [u== #Symbol or:u=3]]ifTrue:[
+                    uu := 4.
+
+                    ].
+
+                    '.
+ self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:collector tree expression isBlock.
+    self assert:collector tree expression statements expression isMessage.
+    self assert:collector tree expression statements expression receiver isBinaryMessage.
+    self assert:collector tree expression statements expression receiver receiver isVariable.
+    self assert:collector tree expression statements expression receiver receiver name = 'u'.
+    self assert:collector tree expression statements expression receiver selector = #'=='.
+    self assert:collector tree expression statements expression receiver args size = 1.
+    self assert:collector tree expression statements expression receiver arg isConstant.
+    self assert:collector tree expression statements expression receiver arg value = #Symbol.
+    self assert:collector tree expression statements expression selector = #or:.
+    self assert:collector tree expression statements expression args size = 1.
+    self assert:collector tree expression statements expression arg1 isBinaryMessage.
+    self assert:collector tree nextStatement expression isErrorNode.
+    self assert:collector tree nextStatement expression errorToken = ']'.
+    self 
+        assert:collector tree nextStatement nextStatement expression isMessage.
+    self 
+        assert:collector tree nextStatement nextStatement expression receiver 
+                isErrorNode.
+    self 
+        assert:collector tree nextStatement nextStatement expression receiver 
+                errorToken = 'Keyword'.
+    self 
+        assert:collector tree nextStatement nextStatement expression selector 
+                = #ifTrue:.
+    self 
+        assert:collector tree nextStatement nextStatement expression args size = 1.
+    self 
+        assert:collector tree nextStatement nextStatement expression arg1 
+                statements expression 
+                isAssignment.
+
+    "Created: / 16-02-2011 / 16:47:18 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 20:56:11 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test36
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |uu w|
+                    [u== #Symbol ifTrue:[
+                    uu := 4.
+
+                    ].
+
+                    '.
+   self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:collector tree expression isBlock.
+    self assert:collector tree expression statements expression isMessage.
+    self assert:collector tree expression statements expression receiver isBinaryMessage.
+    self assert:collector tree expression statements expression receiver receiver isVariable.
+    self assert:collector tree expression statements expression receiver receiver name = 'u'.
+    self assert:collector tree expression statements expression receiver selector = #'=='.
+    self assert:collector tree expression statements expression receiver args size = 1.
+    self assert:collector tree expression statements expression receiver arg isConstant.
+    self assert:collector tree expression statements expression receiver arg value = #Symbol.
+    self assert:collector tree expression statements expression selector = #ifTrue: .
+    self assert:collector tree expression statements expression args size = 1.
+    self assert:collector tree expression statements expression arg1 isBlock.
+    self assert:collector tree expression statements expression arg1 statements expression 
+                isAssignment.
+
+    "Created: / 16-02-2011 / 16:48:07 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 21:13:22 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test37
+    |collector|
+
+    collector := self 
+                doForSource:'  
+                    |uu w|
+                    [u== #Symbol) ifTrue:[
+                    uu := 4.
+
+                    ].
+
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:collector tree expression isBlock.
+    self 
+        assert:collector tree expression statements expression isBinaryMessage.
+    self 
+        assert:collector tree expression statements expression receiver name = 'u'.
+    self 
+        assert:collector tree expression statements expression selector = #'=='.
+    self assert:collector tree expression statements expression args size = 1.
+    self 
+        assert:collector tree expression statements expression arg1 value = #Symbol.
+    self 
+        assert:collector tree expression statements nextStatement expression 
+                isErrorNode.
+    self 
+        assert:collector tree expression statements nextStatement expression 
+                errorToken = ')'.
+    self 
+        assert:collector tree expression statements nextStatement nextStatement 
+                expression isMessage.
+    self 
+        assert:collector tree expression statements nextStatement nextStatement expression 
+                receiver isErrorNode.
+    self 
+        assert:collector tree expression statements nextStatement nextStatement expression 
+                receiver errorToken 
+                = 'Keyword'.
+    self 
+        assert:collector tree expression statements nextStatement nextStatement expression 
+                selector = #ifTrue:.
+    self 
+        assert:collector tree expression statements nextStatement nextStatement expression args 
+                size = 1.
+    self 
+        assert:collector tree expression statements nextStatement nextStatement expression arg1 
+                isBlock.
+    self 
+        assert:collector tree expression statements nextStatement nextStatement expression arg1 
+                statements expression 
+                isAssignment.
+
+    "Created: / 16-02-2011 / 17:21:06 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 21:25:27 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test38
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |uu w|
+                    [:=
+
+                    ].
+
+                    '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isBlock.
+self assert:collector tree expression statements expression  isErrorNode.
+self assert:collector tree expression statements expression errorToken=':='.
+
+    "Created: / 18-02-2011 / 11:55:35 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 21:40:40 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test39
+    |collector|                
+    collector := self 
+                doForSource:'  
+                    |uu w|
+                    :=3
+
+                    '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isErrorNode.
+self assert:collector tree expression errorToken=':='.
+self assert:collector tree  nextStatement expression isConstant.
+self assert:collector tree  nextStatement expression value=3.
+
+    "Created: / 18-02-2011 / 17:11:24 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test4
+    |collector|
+
+    collector := self doForSource:'
+                    u 3'.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression) isUnaryMessage.
+    self assert:(collector tree expression receiver name = 'u').
+    self assert:(collector tree expression receiver) isVariable.
+    self assert:(collector tree expression selector asString) = '3'.
+
+    "Created: / 15-02-2011 / 14:13:48 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:10:14 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test40
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |array tokenValue|
+                  self rememberSymbolUsed:tokenValue
+                    array:=( 3 4 5 6.           '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isMessage.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement  expression isUnaryMessage.
+
+    "Created: / 18-02-2011 / 20:17:31 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test41
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |array tokenValue|
+                  self rememberSymbolUsed:tokenValue
+                    array:=( 3 4 5 6 :=u           '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isMessage.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement  expression isUnaryMessage.
+self assert:collector tree nextStatement nextStatement nextStatement  expression isErrorNode.
+self assert:collector tree nextStatement nextStatement nextStatement  expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement nextStatement nextStatement  expression isVariable.
+
+    "Created: / 18-02-2011 / 20:35:35 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test42
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |array tokenValue|
+                  self rememberSymbolUsed:tokenValue
+                    array:= 3 4 5 6 :=u)           '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isMessage.
+self assert:collector tree nextStatement expression isErrorNode.
+self assert:collector tree nextStatement expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement  expression isUnaryMessage.
+self assert:collector tree nextStatement nextStatement nextStatement  expression isErrorNode.
+self assert:collector tree nextStatement nextStatement nextStatement  expression errorToken=':='.
+self assert:collector tree nextStatement nextStatement nextStatement nextStatement  expression isVariable.
+self assert:collector tree nextStatement nextStatement nextStatement nextStatement nextStatement expression isErrorNode.
+self assert:collector tree nextStatement nextStatement nextStatement nextStatement nextStatement expression errorToken=')'.
+
+    "Created: / 18-02-2011 / 20:37:17 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test43
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |uu w b|
+                    [u== #Symbol ifTrue:[
+                    uu := 4.
+
+                    ].
+                      b:=3
+                    '.
+   self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:collector tree expression isBlock.
+    self assert:collector tree expression statements expression isMessage.
+    self assert:collector tree expression statements expression receiver isBinaryMessage.
+    self assert:collector tree expression statements expression receiver receiver isVariable.
+    self assert:collector tree expression statements expression receiver receiver name = 'u'.
+    self assert:collector tree expression statements expression receiver selector = #'=='.
+    self assert:collector tree expression statements expression receiver args size = 1.
+    self assert:collector tree expression statements expression receiver arg isConstant.
+    self assert:collector tree expression statements expression receiver arg value = #Symbol.
+    self assert:collector tree expression statements expression selector = #ifTrue: .
+    self assert:collector tree expression statements expression args size = 1.
+    self assert:collector tree expression statements expression arg1 isBlock.
+    self assert:collector tree expression statements expression arg1 statements expression 
+                isAssignment.
+
+    "Created: / 18-02-2011 / 21:16:10 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test44
+    |collector|
+    collector := self 
+                doForSource:'  
+                    |b c|
+                   u :=b b: u:c
+                    '.
+self assert:collector notNil.
+self assert:collector tree notNil.
+self assert:collector tree expression isAssignment.
+
+    "Created: / 20-02-2011 / 18:54:11 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test45
+    |collector|
+    collector := self 
+                doForSource:'
+                    | a b |
+                    a := [self pr   
+                    b := self navigationState isFullClassSourceBrowser
+                                                    or:[self isJavaMethod and:[JavaMethod showFullSource]].     
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:collector tree expression isAssignment.
+    self assert:collector tree expression expression isBlock.
+    self assert:collector tree expression expression statements isStatement.
+    self assert:collector tree expression expression statements expression isErrorNode.
+    self assert:collector tree expression expression statements expression children first isMessage.
+    self assert:collector tree expression expression statements expression children first selector = 'pr'.
+
+    "Created: / 19-09-2013 / 11:19:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test46
+    |collector|
+    collector := self 
+                doForSource:'
+                    | a b |
+                    a := a and:[self pr   
+                    b := self navigationState isFullClassSourceBrowser
+                                                    or:[self isJavaMethod and:[JavaMethod showFullSource]].     
+                    '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:collector tree expression isAssignment.
+    self assert:collector tree expression expression isMessage.
+    self assert:collector tree expression expression args last isBlock.
+    self assert:collector tree expression expression args last statements expression isErrorNode.
+    self assert:collector tree expression expression args last statements expression children first isMessage.
+    self assert:collector tree expression expression args last statements expression children first selector = 'pr'.
+
+    "Created: / 19-09-2013 / 11:48:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test47
+    |collector|
+    collector := self 
+                doForSource:'
+                    |mthd doScrollToTop code codeView doAutoFormat doSyntaxColoring doUpdateCode prevMthd doShowFullClassSource |
+
+                    doAutoFormat := self doAutoFormat value and:[RBFormatter notNil and:[mthd prog
+                    doShowFullClassSource := self navigationState isFullClassSourceBrowser
+                                                or:[mthd isJavaMethod and:[JavaMethod showFullSource]].
+                    doUpdateCode := true.
+                    codeView := self codeView.
+                    self assert:codeView notNil.
+
+                    code := self sourceOfMethod:mthd.
+                    code isText ifTrue:[
+                        "/Already done...
+                        doSyntaxColoring := false.
+                    ] ifFalse:[
+                        "/Do no coloring here if CodeView2 is used,
+                        "/since CodeView2 itself cares about the coloring!!
+                        "/Not working correctly -> do the coloring until fixed in CodeView2
+                        "/JV: Then make a bug report because otherwise it won''t be
+                        "/    ever fixed.
+                        "(UserPreferences current useCodeView2In: #Browser)"false ifTrue:[
+                            doSyntaxColoring := code size < 2000
+                        ] ifFalse:[
+                            doSyntaxColoring := self doSyntaxColoring value == true.
+                        ].
+                    ].
+
+
+                    doAutoFormat ifTrue:[
+                        Error catch:[
+                            code := RBFormatter format:code
+                        ].
+                    ].
+
+                    doShowFullClassSource ifTrue:[
+                        "As whole class source coce is shown,
+                         there is no need to set codeview''s content if previous method
+                         belonged to the same class. Code is already shown, we need only
+                         to scrool to it..."
+                        "hmm...hmm...how implement it in a better, more generic way?"        
+                        mthd isSynthetic not ifTrue:[
+                            prevMthd := navigationState lastMethodShownInCodeView.
+                            prevMthd notNil ifTrue:[
+                                doUpdateCode := prevMthd isSynthetic or:[mthd mclass ~~ prevMthd mclass]
+                            ].
+
+
+                        ].
+                    ].
+                    doUpdateCode ifTrue:[
+                        doSyntaxColoring ifTrue:[
+                            "/ immediate coloring, if code is not too large;
+                            "/ otherwise, do it in the background.
+                            code size < 2000 " 10000 " ifTrue:[
+                                Error handle:[:ex |
+                                    Transcript showCR:''error in syntaxHighlighter: '',ex description.
+                                ] do:[
+                                    code := self syntaxHighlightedCodeFor:code method:mthd.
+                                ].
+                            ] ifFalse:[
+                                self enqueueDelayedStartSyntaxHighlightProcess.
+                            ].
+
+                            [
+                                codeView modifiedChannel removeDependent:self.
+                                codeView modified:false.
+                                self showCode:code scrollToTop:doScrollToTop.
+                            ] ensure:[
+                                codeView modifiedChannel addDependent:self.
+                            ]
+                        ] ifFalse:[
+                            self showCode:code scrollToTop:doScrollToTop.
+                        ].
+                    ].
+                    navigationState lastMethodShownInCodeView: mthd.
+
+                    "/ scroll, for file-based classes (java, ruby, etc.)
+                    doShowFullClassSource ifTrue:[
+                        mthd sourceLineNumber ~~ 1 ifTrue:[
+                            doScrollToTop ifTrue:[ "/ifFalse:[
+                                codeView scrollToLine:mthd sourceLineNumber
+                            ]
+                        ].
+                    ].
+                    self codeAspect:(code ifNil:[nil] ifNotNil:[SyntaxHighlighter codeAspectMethod]).
+                    self normalLabel.
+                    self updatePackageInfoForMethod:mthd.'.
+
+    self assert: collector tree notNil.
+
+    "Created: / 19-09-2013 / 11:54:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-09-2013 / 00:58:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test5
+    |collector|
+
+    collector := self doForSource:'
+                    u +'.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression) isBinaryMessage.
+    self assert:(collector tree expression receiver name = 'u').
+    self assert:(collector tree expression receiver) isVariable.
+    self assert:(collector tree expression selector) isSymbol.
+    self assert:(collector tree expression selector asString) = '+'.
+    self assert:(collector tree expression args size) = 1.
+    self assert:(collector tree expression arg) isErrorNode.
+    self assert:(collector tree expression arg errorToken = 'EOF').
+
+    "Created: / 15-02-2011 / 15:18:25 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 15:31:37 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test6
+    |collector|
+
+    collector := self doForSource:'
+                    u +.'.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression) isBinaryMessage.
+    self assert:(collector tree expression receiver name = 'u').
+    self assert:(collector tree expression receiver) isVariable.
+    self assert:(collector tree expression selector) isSymbol.
+    self assert:(collector tree expression selector asString) = '+'.
+    self assert:(collector tree expression args size) = 1.
+    self assert:(collector tree expression arg) isErrorNode.
+    self assert:(collector tree expression arg errorToken = '.').
+
+    "Created: / 15-02-2011 / 15:19:08 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 15:32:56 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test7
+    |collector|
+
+    collector := self doForSource:'
+                    u 3.'.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression) isUnaryMessage.
+    self assert:(collector tree expression receiver name = 'u').
+    self assert:(collector tree expression receiver) isVariable.
+    self assert:(collector tree expression selector asString) = '3'.
+
+    "Created: / 15-02-2011 / 15:19:22 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 22:10:21 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test8
+    |collector|
+
+    collector := self doForSource:'
+                    u =.'.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression) isBinaryMessage.
+    self assert:(collector tree expression receiver name = 'u').
+    self assert:(collector tree expression receiver) isVariable.
+    self assert:(collector tree expression selector) == #'='.
+    self assert:(collector tree expression args size) = 1.
+    self assert:(collector tree expression arg) isErrorNode.
+    self assert:(collector tree expression arg errorToken = '.').
+
+    "Created: / 15-02-2011 / 15:19:38 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 15:34:13 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+test9
+    |collector|
+
+    collector := self doForSource:'
+                    u :.'.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression name = 'u').
+    self assert:(collector tree expression) isVariable.
+    self assert:(collector tree nextStatement expression isErrorNode).
+    self assert:collector tree nextStatement expression errorToken = ':'.
+    self assert:collector tree nextStatement nextStatement isNil.
+
+    "Created: / 15-02-2011 / 15:19:52 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-02-2011 / 15:35:42 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+testBadAssignment
+    |collector|
+
+    collector := self doForSource:'
+                    u := '.
+    self assert:collector notNil.
+    self assert:collector tree notNil.
+    self assert:(collector tree expression) isAssignment.
+    self assert:(collector tree expression variable name = 'u').
+    self assert:(collector tree expression variable) isVariable.
+    self assert:(collector tree expression expression) isErrorNode.
+    self assert:(collector tree expression expression errorToken = 'EOF').
+
+    "Modified: / 18-02-2011 / 15:39:33 / Jakub <zelenja7@fel.cvut.cz>"
+! !
+
+!SmalltalkParserTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkQuickFixer.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,198 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#SmalltalkQuickFixer
+	instanceVariableNames:'view rule fixes'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Lint'
+!
+
+Object subclass:#QuickFix
+	instanceVariableNames:'rule label action'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:SmalltalkQuickFixer
+!
+
+!SmalltalkQuickFixer class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkQuickFixer class methodsFor:'instance creation'!
+
+forView: view
+
+    ^self new initializeForView: view
+
+    "Created: / 15-12-2014 / 16:45:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkQuickFixer methodsFor:'accessing'!
+
+fixesForRule: rule
+    ^ fixes select:[:fix | fix rule == rule ]
+
+    "Created: / 15-12-2014 / 16:47:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkQuickFixer methodsFor:'adding'!
+
+fix
+    "Create and return new quick fix. Caller MUST set its 
+     rule, label and action"
+
+    | fix |
+
+    fix := QuickFix new.
+    fixes add: fix.
+    ^fix
+
+    "Created: / 01-02-2012 / 10:51:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 15-12-2014 / 16:48:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkQuickFixer methodsFor:'initialization'!
+
+initializeForView: aCodeView2
+    view := aCodeView2.
+    fixes := OrderedCollection new: 3.
+
+    "Created: / 15-12-2014 / 16:46:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkQuickFixer methodsFor:'performing fixes'!
+
+performFix: index
+
+    index <= fixes size ifTrue:[
+        (fixes at: index) performFix.
+    ] ifFalse:[
+        ^ Dialog warn: ('No such fix (%1)' bindWith: index).
+    ]
+
+    "Created: / 16-02-2012 / 14:48:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkQuickFixer methodsFor:'utilities'!
+
+apply: changes 
+    changes isEmptyOrNil ifTrue: [
+        ^ self
+    ].
+    (changes size == 1 and: [ changes anElement isMethodCodeChange ]) ifTrue: [
+        "/ Only one change, modify the code directly in the editor
+
+        | oldSource newSource |
+
+        oldSource := view contents asString string.
+        newSource := changes anElement source asString.
+        oldSource ~= newSource ifTrue: [
+            | line |
+
+            line := view firstLineShown.
+            view contents: newSource asStringCollection clear: false.
+            view modified: true.
+            view isCodeView2 ifTrue: [
+                view reallyModifiedChannel value: true.
+            ].
+            view scrollToLine:line.     
+        ].
+    ] ifFalse: [
+        | browser |
+
+        browser := view application topApplication.
+        (browser respondsTo: #performRefactoring:) ifTrue: [
+            browser performRefactoring: changes.
+        ] ifFalse: [
+            self breakPoint: #jv.
+            Dialog warn:'Sorry, this application does not support quick fixes'
+        ]
+    ]
+
+    "Created: / 16-02-2012 / 14:46:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-10-2014 / 03:05:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkQuickFixer::QuickFix methodsFor:'accessing'!
+
+action
+    ^ action
+!
+
+action:aBlock
+    action := aBlock.
+!
+
+label
+    ^ label
+!
+
+label:aString
+    label := aString.
+!
+
+performFix
+
+    ^action value
+
+    "Created: / 16-02-2012 / 14:48:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+rule
+    ^ rule
+!
+
+rule:anRBLintRule
+    rule := anRBLintRule.
+! !
+
+!SmalltalkQuickFixer class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkSyntaxHighlighter.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,630 @@
+"
+ COPYRIGHT (c) 2010 by Jan Vrany, SWING Research Group. CTU in Prague
+	      All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the 'Software'), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+SyntaxHighlighter subclass:#SmalltalkSyntaxHighlighter
+	instanceVariableNames:'elements lastVariableElements lastSelectorElement
+		ignoreBadIdentifier'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk'
+!
+
+!SmalltalkSyntaxHighlighter class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2010 by Jan Vrany, SWING Research Group. CTU in Prague
+	      All Rights Reserved
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the 'Software'), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+"
+! !
+
+!SmalltalkSyntaxHighlighter class methodsFor:'highlighting'!
+
+format:aString parsingWith:aBlock in:aClass elementsInto:elements
+    "common code for formatStatementList, formatExpression, ...
+     format (recolor) whatever is parsed in aBlock (within the context of a given class).
+     Return the text containing font changes and color information.
+     As a side effect, put syntax elements into the passed in elements container
+     (for element-highlighting in codeView2)"
+
+    |parser tree text endPos|
+
+    aString isNil ifTrue:[^ nil].
+
+    parser := self for:(ReadStream on:aString string) in:aClass.
+    parser elements: elements.
+    parser ignoreErrors:true.
+    parser ignoreWarnings:true.
+    parser sourceText:(text := aString string asText).
+    "/ use an array here - this can be changed much faster using #at:put:
+    text emphasisCollection:(Array new:aString size).
+
+    parser nextToken.
+    tree := aBlock value:parser.
+    "/ now, convert the emphasis-array to a runArray
+    text emphasisCollection:(text emphasis asRunArray).
+
+    tree == #Error ifTrue:[
+        "/ mhmh - which is better ...
+        "/ alternative1: color rest after error in red
+"/        text 
+"/            emphasizeFrom:(parser sourceStream position) 
+"/            to:text size 
+"/            with:(#color->Color red).
+
+
+        "/ alternative2: take original emphasis for rest
+
+        endPos := parser sourceStream position + 1.
+        endPos >= text size ifTrue:[
+            ^ text
+        ].
+        ^ ((text copyTo:endPos) , (aString copyFrom:(endPos+1))).
+
+        "/ alternative3: no emphasis for rest.
+
+"/        ^ text "/ aString
+    ].
+    ^ text
+
+    "
+     self
+        formatStatementList:'(1 + 2) max:5. 1 + 2' 
+        in:UndefinedObject
+        elementsInto:(OrderedCollection new).
+    "
+!
+
+formatClassDefinition:aString in:aClass elementsInto: elements
+    "format (recolor) a class definition expression in a given class.
+     Return the text containing font changes and color information."
+
+    ^ self formatExpression:aString in:aClass elementsInto: elements
+
+    "Created: / 10-04-2011 / 18:18:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+formatExpression:aString in:aClass elementsInto: elements
+    "format (recolor) an expression in a given class.
+     Return the text containing font changes and color information."
+
+    |parser tree text endPos|
+
+    aString isNil ifTrue:[^ nil].
+
+    parser := self for:(ReadStream on:aString string) in:aClass.
+    parser elements: elements.
+    parser ignoreErrors:true.
+    parser ignoreWarnings:true.
+    parser sourceText:(text := aString string asText).
+    "/ use an array here - this can be changed much faster using #at:put:
+    text emphasisCollection:(Array new:aString size).
+
+    parser nextToken.
+    tree := parser "expression"statementList.
+    "/ now, convert the emphasis-array to a runArray
+    text emphasisCollection:(text emphasis asRunArray).
+
+    tree == #Error ifTrue:[
+	"/ mhmh - which is better ...
+	"/ alternative1: color rest after error in red
+"/        text
+"/            emphasizeFrom:(parser sourceStream position)
+"/            to:text size
+"/            with:(#color->Color red).
+
+
+	"/ alternative2: take original emphasis for rest
+
+	endPos := parser sourceStream position1Based.
+	endPos >= text size ifTrue:[
+	    ^ text
+	].
+	^ ((text copyTo:endPos) , (aString copyFrom:(endPos+1))).
+
+	"/ alternative3: no emphasis for rest.
+
+"/        ^ text "/ aString
+    ].
+    ^ text
+
+    "
+     self
+	formatExpression:'(1 + 2) max:5'
+	in:UndefinedObject
+    "
+
+    "Created: / 25-07-2010 / 08:56:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-07-2010 / 10:57:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+formatMethod:aString in:aClass using:preferencesOrNil elementsInto: elements
+    "format (recolor) a method in a given class.
+     Return the text containing font changes and color information."
+
+    "/ obsolete interface
+    ^ self
+	formatMethod:nil
+	source:aString
+	in:aClass
+	using:preferencesOrNil elementsInto:elements
+
+    "Created: / 25-07-2010 / 08:56:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 05-07-2011 / 11:07:50 / cg"
+!
+
+formatMethod:aMethodOrNil source:aString in:aClass using:preferencesOrNil elementsInto: elements
+    "format (recolor) a method in a given class.
+     Return the text containing font changes and color information."
+
+    |highlighter tree text endPos eColor|
+
+    aString isNil ifTrue:[^ nil].
+
+    Error handle:[:ex |
+        ex creator isHandled ifTrue:[
+            ex reject.
+        ].
+        (self parseErrorSignal handles:ex) ifFalse:[
+            "Parse error may happen when re-formatting incomplete code while editing"
+            ('SyntaxHighlighter [info]: error during highlight: ' , ex description) infoPrintCR.
+            "/ ex suspendedContext fullPrintAll.
+        ].
+        ^ aString
+    ] do:[
+        highlighter := self for:(ReadStream on:aString string) in:aClass.
+        highlighter elements: elements.
+        preferencesOrNil notNil ifTrue:[highlighter preferences:preferencesOrNil].
+        "/ highlighter ignoreErrors:true.
+        highlighter ignoreWarnings:true.
+        highlighter sourceText:(text := aString string asText).
+        "/ use an array here - this can be changed much faster using #at:put:
+        text emphasisCollection:(Array new:aString size).
+
+        tree := highlighter parseMethod.
+        "/ now, convert the emphasis-array to a runArray
+        text emphasisCollection:(text emphasis asRunArray).
+
+        tree == #Error ifTrue:[
+            eColor := UserPreferences current errorColor.
+            eColor notNil ifTrue:[
+                "/ mhmh - which is better ...
+                "/ alternative1: color rest after error in red
+                text
+                    emphasizeFrom:(highlighter sourceStream position + 1) 
+                    to:text size
+                    with:(#color->eColor).
+            ] ifFalse:[
+                "/ alternative2: take original emphasis for rest
+
+                endPos := highlighter sourceStream position + 1.
+                endPos >= text size ifTrue:[
+                    ^ Array with: text with: highlighter elements
+                ].
+                ^ ((text copyTo:endPos) , (aString copyFrom:(endPos+1)))
+            ].
+            "/ alternative3: no emphasis for rest.
+        ].
+        ^text
+    ]
+    "
+     self
+        formatMethod:'foo
+    ^ self bar:''hello''.
+
+    ' , (Character doubleQuote asString) , 'some comment' , (Character doubleQuote asString) , '
+'
+        in:UndefinedObject
+    "
+
+    "Modified: / 22-08-2006 / 13:32:04 / cg"
+    "Created: / 05-07-2011 / 10:39:21 / cg"
+    "Modified: / 28-05-2013 / 22:45:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkSyntaxHighlighter methodsFor:'accessing'!
+
+elements
+    ^ elements
+!
+
+elements:aParseTreeIndex
+    "the element collection, to collect variables, selectors etc. into"
+
+    elements := aParseTreeIndex.
+
+    "Modified (comment): / 21-08-2011 / 09:13:31 / cg"
+!
+
+tree: aParseNode
+    super tree: aParseNode.
+    elements tree: aParseNode
+
+    "Created: / 16-02-2012 / 09:56:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkSyntaxHighlighter methodsFor:'initialization'!
+
+initialize
+
+    super initialize.
+    elements := ParseTreeIndex new.
+    lastVariableElements := Dictionary new.
+
+    "Created: / 14-02-2010 / 13:08:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-08-2011 / 09:37:35 / cg"
+    "Modified: / 16-02-2012 / 09:59:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkSyntaxHighlighter methodsFor:'parsing-expressions'!
+
+binaryExpressionFor:receiverArg
+    "parse a binary-expression; return a node-tree, nil or #Error"
+
+    |receiver expr arg sel pos1 pos2 lno|
+
+    receiver := receiverArg.
+    (receiver == #Error) ifTrue:[^ #Error].
+
+    "special kludge: since Scanner cannot know if -digit is a binary
+     expression or a negative constant, handle cases here"
+
+    [(tokenType == #BinaryOperator) 
+     or:[(tokenType == $|)
+     or:[(tokenType == $^ and:[parserFlags allowCaretAsBinop])
+         or:[((tokenType == #Integer) or:[tokenType == #Float])
+             and:[tokenValue < 0]]]]
+    ] whileTrue:[
+        "/ kludge alarm: in a function-call argList, #, is not a binarySelector
+        inFunctionCallArgument == true ifTrue:[
+            ((tokenType == #BinaryOperator) and:[tokenName = ',']) ifTrue:[
+                ^ receiver
+            ].
+        ].
+
+        pos1 := tokenPosition.
+        lno := tokenLineNr.
+
+        "/ kludge alarm: bar, caret and minus are not scanned as binop
+        (tokenType == $|) ifTrue:[
+            sel := '|'.
+            sel := self selectorCheck:sel for:receiver position:tokenPosition to:tokenPosition.
+            self nextToken.
+        ] ifFalse:[
+            (tokenType == $^) ifTrue:[
+                sel := '^'.
+                sel := self selectorCheck:sel for:receiver position:tokenPosition to:tokenPosition.
+                self nextToken.
+            ] ifFalse:[
+                (tokenType == #BinaryOperator) ifTrue:[
+                    sel := tokenName.
+                    sel := self selectorCheck:sel for:receiver position:tokenPosition to:(tokenPosition + tokenName size - 1).
+                    self nextToken
+                ] ifFalse:[
+                    sel := '-'.
+                    token := tokenValue := tokenValue negated.
+                    tokenPosition := tokenPosition + 1. "/ to skip the sign
+                ]
+            ].
+        ].
+
+        pos2 := pos1 + sel size - 1.
+        self markSelector:sel from:pos1 to:pos2 receiverNode:receiver.
+        lastSelectorElement := nil.
+
+        arg := self unaryExpression.
+        (arg == #Error) ifTrue:[^ #Error].
+
+        expr := BinaryNode receiver:receiver selector:sel arg:arg fold:foldConstants.
+        expr isErrorNode ifTrue:[
+            self parseError:(expr errorString) position:pos1 to:tokenPosition.
+            errorFlag := false. "ok, user wants it - so he'll get it"
+            expr := BinaryNode receiver:receiver selector:sel arg:arg fold:nil.
+        ].
+        expr lineNumber:lno.
+        expr selectorPosition:pos1.
+
+        self checkPlausibilityOf:expr from:pos1 to:pos2.
+        receiver := expr.   "/ for next message
+    ].
+    ^ receiver
+
+    "Modified: / 09-01-1998 / 19:05:18 / stefan"
+    "Modified: / 14-02-2010 / 17:54:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-01-2012 / 10:46:49 / cg"
+!
+
+expression
+    | node savedLastSelectorElement |
+
+    savedLastSelectorElement := lastSelectorElement.
+    lastSelectorElement := nil.
+    node := super expression.
+    ((node ~~ #Error) and:[node isMessage]) ifTrue:[
+        [ lastSelectorElement notNil ] whileTrue:[
+            lastSelectorElement node parent: node.
+            lastSelectorElement := lastSelectorElement prev.
+        ].
+    ].
+    lastSelectorElement := savedLastSelectorElement.
+    ^node
+
+    "Modified: / 19-01-2000 / 16:22:16 / cg"
+    "Modified: / 16-02-2012 / 23:39:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+primary_identifier
+    | node |
+
+    ignoreBadIdentifier := classToCompileFor isNil.
+    node := super primary_identifier.
+    ignoreBadIdentifier := false.
+    (node ~~ #Error and:[node isVariable]) ifTrue:[
+        | el prevEl |
+
+        el := elements newElementFor: node.
+        prevEl := lastVariableElements at:node name ifAbsent:[nil].
+        prevEl notNil ifTrue:[prevEl next:el].
+        lastVariableElements at:node name put:el.
+        elements add: el.
+    ].
+    ^node
+
+    "Created: / 24-09-2013 / 00:42:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-10-2013 / 14:43:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+unaryExpressionFor:receiverArg
+    "parse a unary-expression; return a node-tree, nil or #Error"
+
+    |receiver expr sel pos pos2 lNr arguments savedLastSelectorElement|
+
+    savedLastSelectorElement := lastSelectorElement.
+    receiver := receiverArg.
+    (receiver == #Error) ifTrue:[^ #Error].
+
+    [ self isValidUnarySelector:tokenType ] whileTrue:[
+	pos := tokenPosition.
+	pos2 := pos + tokenName size - 1.
+	lNr := tokenLineNr.
+	sel := tokenName.
+
+	lastSelectorElement := nil.
+	self markSelector:sel from:pos to:pos2 receiverNode:receiver.
+
+	self nextToken.
+	tokenType == $( ifTrue:[
+	    parserFlags allowSqueakExtensions == true ifTrue:[
+		"/ croquet/squeak extension - c/java-style arguments
+		arguments := self functionCallArgList.
+		"/ synthetic selector: foo[:[with:[with:[...]]]]
+		arguments notEmpty ifTrue:[
+		    sel := sel , ':'.
+		    arguments size - 1 timesRepeat:[ sel := sel , 'with:' ].
+		].
+		sel := self selectorCheck:sel for:receiver position:pos to:pos2.
+		expr := MessageNode receiver:receiver selector:sel args:arguments fold:foldConstants.
+		expr isErrorNode ifTrue:[
+		    self parseError:(expr errorString) position:pos to:pos2.
+		    errorFlag := false. "ok, user wants it - so he'll get it"
+		    expr := MessageNode receiver:receiver selector:sel args:arguments fold:nil.
+		].
+		lastSelectorElement node parent: expr.
+		expr lineNumber:lNr.
+		self checkPlausibilityOf:expr from:pos to:pos2.
+		parseForCode ifFalse:[
+		    self rememberSelectorUsed:sel receiver:receiver
+		].
+		^ expr.
+	    ].
+	].
+
+	sel := self selectorCheck:sel for:receiver position:pos to:pos2.
+	expr := UnaryNode receiver:receiver selector:sel fold:foldConstants.
+	expr isErrorNode ifTrue:[
+	    self warning:(expr errorString , '.\\If you proceed, that error will happen at runtime.') withCRs position:pos to:pos2.
+	    errorFlag := false. "ok, user wants it - so he'll get it"
+	    expr := UnaryNode receiver:receiver selector:sel fold:nil.
+	].
+	expr lineNumber:lNr.
+	lastSelectorElement node parent: expr.
+
+	self checkPlausibilityOf:expr from:pos to:pos2.
+	parseForCode ifFalse:[
+	    self rememberSelectorUsed:sel receiver:receiver
+	].
+
+	receiver := expr.   "/ for next message
+    ].
+    lastSelectorElement := savedLastSelectorElement.
+    ^ receiver
+
+    "Modified: / 19-01-2012 / 10:47:37 / cg"
+    "Created: / 16-02-2012 / 23:50:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkSyntaxHighlighter methodsFor:'syntax detection'!
+
+markLocalVariableDeclaration: name from:pos1 to:pos2
+    | type node |
+
+    super markLocalVariableDeclaration: name from:pos1 to:pos2.
+
+    type := currentBlock notNil ifTrue:[#BlockVariable] ifFalse:[#MethodVariable].
+    node := VariableNode type: type name: name.
+    node startPosition: pos1 endPosition: pos2.
+    self rememberVariableElementFor: node from: pos1 to: pos2 assigned: false.
+
+    "Created: / 25-02-2014 / 20:22:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+markMethodArgumentIdentifierFrom:pos1 to:pos2
+    | node |
+
+    super markMethodArgumentIdentifierFrom:pos1 to:pos2.
+
+    node := VariableNode methodArgumentNamed:(sourceText string copyFrom: pos1 to: pos2).
+    node startPosition: pos1 endPosition: pos2.    
+    self rememberVariableElementFor: node from:pos1 to:pos2 assigned:false
+
+    "Created: / 24-07-2010 / 09:25:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-08-2011 / 09:27:26 / cg"
+    "Modified: / 25-02-2014 / 12:15:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+markSelector:selectorString from:pos1 to:pos2 receiverNode:aReceiverNode
+
+    | element selectorSymbol |
+
+    "Special hack for Java class references - I would like to have them
+     marked specially (and not as an error when the class is not yet loaded -
+     the code is correct as JavaClassAccessor loads it lazily"
+    (aReceiverNode isJavaPackageReference) ifTrue:[
+	self
+	    markFrom:pos1 to:pos2
+	    withEmphasis:preferences globalClassIdentifierEmphasis
+	    color: preferences globalClassIdentifierColor
+    ] ifFalse:[
+	super markSelector:selectorString from:pos1 to:pos2 receiverNode:aReceiverNode.
+    ].
+
+    "don't create symbols for partial typed selectors"
+    selectorSymbol := selectorString asSymbolIfInterned.
+
+    element := elements newElementFor: (SelectorNode value: selectorString from: pos1 to: pos2).
+
+    (lastSelectorElement notNil "and:[lastSelectorElement value = selectorString]") ifTrue:[
+	lastSelectorElement next: element.
+    ].
+    elements add: element.
+    lastSelectorElement := "(self isValidUnarySelector:tokenType)"false
+				ifTrue:[nil]
+				ifFalse:[element].
+
+    "Created: / 14-02-2010 / 17:40:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-02-2010 / 19:24:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 21-08-2011 / 09:18:21 / cg"
+    "Modified: / 19-04-2012 / 09:53:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+markSelfFrom:pos1 to:pos2
+    | node |
+
+    super markSelfFrom:pos1 to:pos2.
+
+    node := SelfNode new.
+    node startPosition: pos1 endPosition: pos2.  
+    node type: #Self.
+    self rememberVariableElementFor: node from:pos1 to:pos2 assigned:false
+
+    "Created: / 21-08-2011 / 09:15:45 / cg"
+    "Modified: / 25-02-2014 / 21:56:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+markSuperFrom:pos1 to:pos2
+    | node |
+
+    super markSuperFrom:pos1 to:pos2.
+
+    node := SuperNode new.
+    node startPosition: pos1 endPosition: pos2.  
+    node type: #Super.
+    self rememberVariableElementFor: node from:pos1 to:pos2 assigned:false
+
+    "Created: / 25-02-2014 / 21:57:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+markUnknownIdentifierFrom:pos1 to:pos2
+
+    ignoreBadIdentifier == true ifTrue:[ ^ self ].
+
+    super markUnknownIdentifierFrom:pos1 to:pos2
+
+    "Created: / 31.3.1998 / 19:09:26 / cg"
+    "Modified: / 31.3.1998 / 19:10:30 / cg"
+!
+
+markVariable:v from:pos1 to:pos2 assigned:assigned
+    self rememberVariableElementFor:v from:pos1 to:pos2 assigned:assigned.
+    super markVariable:v from:pos1 to:pos2 assigned:assigned.
+
+    "Created: / 25-06-2010 / 13:03:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-08-2011 / 09:26:30 / cg"
+    "Modified: / 25-02-2014 / 14:07:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+rememberVariableElementFor:node from:pos1 to:pos2 assigned:assigned
+    |name typeSymbol element prev|
+
+    name := node name.
+    typeSymbol := node type.
+    prev := (lastVariableElements at:typeSymbol ifAbsentPut:[Dictionary new]) at:name ifAbsent:[nil].
+    (prev notNil and:[prev start == pos1]) ifTrue:[
+"/        prev assigned:assigned.
+        ^ self
+    ].
+
+    element := elements newElementFor: node.
+
+    prev notNil ifTrue:[prev next:element].
+    (lastVariableElements at:typeSymbol) at:name put:element.
+
+    elements add: element.
+
+    "Created: / 25-02-2014 / 12:13:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkSyntaxHighlighter class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SmalltalkUnacceptedMethodEnvironment.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,138 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+BrowserEnvironment subclass:#SmalltalkUnacceptedMethodEnvironment
+	instanceVariableNames:'class method'
+	classVariableNames:'UnacceptedSelector'
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Lint'
+!
+
+!SmalltalkUnacceptedMethodEnvironment class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SmalltalkUnacceptedMethodEnvironment class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    UnacceptedSelector := #'* * UnacceptedSelector * *'
+
+    "Modified: / 27-01-2012 / 16:23:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkUnacceptedMethodEnvironment class methodsFor:'instance creation'!
+
+onClass: realClass methodSource: source
+
+    ^self new setupForClass: realClass source: source
+
+    "Created: / 27-01-2012 / 15:38:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkUnacceptedMethodEnvironment methodsFor:'accessing'!
+
+methodsInto:arg
+    "raise an error: must be redefined in concrete subclass(es)"
+
+    ^ self shouldImplement
+!
+
+selectorsForClass: aClass do: aBlock
+
+    self assert: aClass == class.
+    aBlock value: (method selector) ? UnacceptedSelector
+
+    "Created: / 27-01-2012 / 15:50:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkUnacceptedMethodEnvironment methodsFor:'accessing-classes'!
+
+classesDo: aBlock 
+
+    ^aBlock value: class.
+
+    "Created: / 27-01-2012 / 15:48:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkUnacceptedMethodEnvironment methodsFor:'initialization'!
+
+setupForClass: realClass source: source
+
+    | ns |
+
+    ns := RBNamespace onEnvironment: BrowserEnvironment new.
+    class := realClass isMetaclass 
+                ifTrue:[RBMetaclass existingNamed: realClass theNonMetaclass name]
+                ifFalse:[RBClass existingNamed: realClass name].
+    class model: ns.
+    method := RBMethod for: class source: source selector: nil.
+    class addMethod: method.
+
+    "Created: / 27-01-2012 / 15:42:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkUnacceptedMethodEnvironment methodsFor:'testing'!
+
+includesSelector: aSelector in: aClass
+
+    ^aClass == method mclass 
+        and:[aSelector == #'  fake selector  '].
+
+    "Created: / 27-01-2012 / 15:51:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SmalltalkUnacceptedMethodEnvironment class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
+
+SmalltalkUnacceptedMethodEnvironment initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__SnippetPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,99 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#SnippetPO
+	instanceVariableNames:'value'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!SnippetPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!SnippetPO methodsFor:'accessing'!
+
+label
+    "Return a text to be displayed. The label may be cached
+     `label` instvar."
+
+    ^ value
+
+    "Created: / 20-05-2014 / 11:30:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage:aProgrammingLanguage
+    "Answers a string to complete"
+
+    ^ value
+
+    "Created: / 20-05-2014 / 11:33:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+value
+    ^ value
+!
+
+value:aString
+    value := aString.
+
+    "Created: / 20-05-2014 / 10:08:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 20-05-2014 / 11:34:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!SnippetPO methodsFor:'testing'!
+
+isSmallSenseSnippetPO
+    ^ true
+! !
+
+!SnippetPO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TestCase.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#TestCase
+	instanceVariableNames:'u v'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests-Obsolete'
+!
+
+!TestCase class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!TestCase class methodsFor:'testing'!
+
+isAbstract
+
+    ^self == SmallSense::TestCase
+
+    "Created: / 03-04-2011 / 22:54:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-08-2013 / 21:47:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TestCase methodsFor:'generate'!
+
+doForSource:src 
+    |parser|
+
+    parser := SmalltalkParser new.
+"/    parser sourceText:('gen',src) asText.
+    parser 
+        parseMethod:'gen' , src
+        in:self class
+        ignoreErrors:false
+        ignoreWarnings:false.
+    ^ parser.
+
+    "Created: / 16-03-2011 / 12:27:38 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 18-03-2011 / 21:57:21 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 19-09-2013 / 11:34:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+processMethod: aCompiledMethod
+        "Fail by default. Needs to be overridden by subclasses to trigger the base testing backbone."
+
+        | collector |
+        collector := SmallSenseTypeCollector onClass: self class.
+        collector currentExtractedMethod: aCompiledMethod.
+        SmallSenseTypeCollector new newExtractor
+                extractInterfacesFrom: aCompiledMethod source class:aCompiledMethod mclass
+                addTo: collector.
+        ^collector
+
+    "Created: / 17-03-2011 / 16:56:07 / Jakub <zelenja7@fel.cvut.cz>"
+    "Modified: / 03-04-2011 / 22:53:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TestCase class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TokenPatternMatcher.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,190 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Regex::RxMatcher subclass:#TokenPatternMatcher
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Utils-Matcher'
+!
+
+!TokenPatternMatcher class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    A custom regex-like matcher to match token streams.
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!TokenPatternMatcher methodsFor:'accessing'!
+
+subexpression: subIndex
+    "returns the matches for a parenthized subexpression.
+     notice that non-matching subexpressions deliver an empty matchString;
+     also be careful with nested parnethesis.
+     With index==1, you get the whole matchString"
+
+    | originalPosition start end reply |
+
+    originalPosition := self position.
+    start := self subBeginning: subIndex.
+    end := self subEnd: subIndex.
+    (start isNil or: [end isNil]) ifTrue: [^''].
+    reply := (Array new: end first - start first) writeStream.
+    self position: start.
+    start first to: end first - 1 do: [:ignored | reply nextPut: stream next].
+    self position: originalPosition.
+    ^reply contents
+
+    "
+     |matcher|
+
+     matcher := Regex::RxMatcher new 
+                    initializeFromString:'(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[ ]+(:isDigit::isDigit:?)[ ]*,[ ]*19(:isDigit::isDigit:)'
+                    ignoreCase:false.
+     (matcher matches:'Aug 6, 1996') ifTrue:[
+        matcher subexpression:2
+     ] ifFalse:[
+        self error.
+     ].                       
+    "
+
+    "Created: / 06-05-2014 / 15:46:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-06-2014 / 17:33:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternMatcher methodsFor:'double dispatch'!
+
+syntaxToken: tokenNode
+    | type value |
+
+    type := tokenNode type.
+    value := tokenNode value.
+
+    ^ Regex::RxmPredicate new predicate:
+        [:token |
+            (token isSymbol or:[token isCharacter]) ifTrue:[ 
+                (type == token) and:[ value isNil or:[value == token ] ]
+            ] ifFalse:[ 
+                (type == token type) and:[ value isNil or:[value = token value]  ]
+            ].
+        ].
+
+    "Created: / 06-05-2014 / 14:38:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 06-05-2014 / 15:59:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+syntaxTokenSet: tokenSetNode
+    | tokens|
+
+    tokens := tokenSetNode tokens.
+
+    ^ Regex::RxmPredicate new predicate:
+        [:token |
+            | matches |
+            matches := tokens anySatisfy:[:tokenNode |
+                | type value |
+
+                type := tokenNode type.
+                value := tokenNode value.
+                (token isSymbol or:[token isCharacter]) ifTrue:[ 
+                    (type = token) and:[ value isNil or:[value == token ] ]
+                ] ifFalse:[ 
+                    (type = token type) and:[ value isNil or:[value = token value]  ]
+                ].
+            ].
+            tokenSetNode negated ifTrue:[ 
+                matches := matches not.
+            ].
+            matches.
+        ].
+
+    "Created: / 09-05-2014 / 16:22:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternMatcher methodsFor:'initialize-release'!
+
+initialize: syntaxTreeRoot ignoreCase: aBoolean
+        "Compile myself for the regex with the specified syntax tree.
+        See comment and `building' protocol in this class and 
+        #dispatchTo: methods in syntax tree components for details 
+        on double-dispatch building. 
+        The argument is supposedly a RxsRegex."
+
+        ignoreCase := aBoolean.
+        self buildFrom: syntaxTreeRoot.
+"/        startOptimizer := RxMatchOptimizer new initialize: syntaxTreeRoot ignoreCase: aBoolean
+
+    "Created: / 06-05-2014 / 14:39:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternMatcher methodsFor:'streaming'!
+
+position
+    ^ Array with: stream position with: stream sourceStream position
+
+    "Created: / 13-06-2014 / 16:52:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+position: positionsPair 
+    [
+        stream position:positionsPair first.
+    ] on: Stream positionErrorSignal do:[
+        "/ No that much tokens in backlog, reset backlog
+        "/ and set source stream's position
+        stream position: positionsPair first sourcePosition: positionsPair second.
+    ]
+
+    "Created: / 13-06-2014 / 16:53:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TokenPatternMatcherTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,190 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#TokenPatternMatcherTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Tests'
+!
+
+!TokenPatternMatcherTests class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!TokenPatternMatcherTests methodsFor:'tests'!
+
+test_01
+
+    | pattern matcher |
+
+    pattern := SmallSense::TokenPatternParser parse: '][[:Keyword=do\::]]'.
+    matcher := SmallSense::TokenPatternMatcher for: pattern.
+
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '] do:'))).
+    self deny:   (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: 'self matches do:'))).
+
+    "Created: / 06-05-2014 / 16:29:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-05-2014 / 16:36:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_02
+
+    | pattern matcher |
+
+    pattern := SmallSense::TokenPatternParser parse: '\[ ( (\:[[:Identifier:]])+ \| )? \.'.
+    matcher := SmallSense::TokenPatternMatcher for: pattern.
+
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '[ .'))).
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '[ :arg1 | .'))).
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '[ :arg1 :arg2 | .'))).
+
+    self deny: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '[ :arg1 arg2 | .'))).
+
+    "Created: / 06-05-2014 / 17:04:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-05-2014 / 17:27:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_03a
+
+    | pattern matcher |
+
+    pattern := SmallSense::TokenPatternParser parse: '[[:import:]] ( [[:Identifier:]](.[[:Identifier:]])*\.?\*? )?'.
+    matcher := SmallSense::TokenPatternMatcher for: pattern.
+
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import '))).
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList'))).
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.concurent.ArrayList'))).
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList.*'))).
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList.'))).
+
+    "Created: / 14-05-2014 / 16:13:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_03b
+
+    | pattern stream matcher matches match |
+
+    pattern := SmallSense::TokenPatternParser parse: '[[:import:]] ( [[:Identifier:]](.[[:Identifier:]])*\.?\*? )?'.
+    matcher := SmallSense::TokenPatternMatcher for: pattern.
+
+
+    stream := SmallSense::TokenStream on: (JavaScanner for: 'import ').
+
+    matches := matcher matchesOnStream: stream.
+    self assert: matches size == 1.
+    match := matches first.
+    self assert: match size == 1.
+    self assert: match first type == #import.
+
+    stream reset.
+
+    matches := matcher matchesOnStream: stream.
+    self assert: matches size == 1.
+    match := matches first.
+    self assert: match size == 1.
+    self assert: match first type == #import.
+
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList'))).
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.concurent.ArrayList'))).
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList.*'))).
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList.'))).
+
+    "Created: / 14-05-2014 / 16:15:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_03c
+
+    | pattern stream matcher matches match |
+
+    pattern := SmallSense::TokenPatternParser parse: '[[:import:]] ( [[:Identifier:]](.[[:Identifier:]])*\.?\*? )?'.
+    matcher := SmallSense::TokenPatternMatcher for: pattern.
+
+
+    stream := SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList.*').
+
+    matches := matcher matchesOnStream: stream.
+    self assert: matches size == 1.
+    match := matches first.
+    self assert: match size == 8.
+    self assert: match first type == #import.
+    self assert: match second type == #Identifier.
+    self assert: match third type == $..
+    self assert: match last type == $*.
+
+
+
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList'))).
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.concurent.ArrayList'))).
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList.*'))).
+"/    self assert: (matcher searchStream: (SmallSense::TokenStream on: (JavaScanner for: 'import java.util.ArrayList.'))).
+
+    "Created: / 14-05-2014 / 16:20:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_04a 
+    "Test of cursor special token (CARRET)"
+
+    | pattern matcher |
+
+    pattern := SmallSense::TokenPatternParser parse: '][[:Keyword=do\::]] [[:CARET:]]'.
+    matcher := SmallSense::TokenPatternMatcher for: pattern.
+
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '] do: [:each |  ] ') cursor:6 )).
+    self deny: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '] do: [:each |  ] ') cursor:8 )).
+
+    "Created: / 15-05-2014 / 16:24:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_04b 
+    "Test of cursor special token (CARRET)"
+
+    | pattern matcher |
+
+    pattern := SmallSense::TokenPatternParser parse: '\[ [[:CARET:]] \]'.
+    matcher := SmallSense::TokenPatternMatcher for: pattern.
+
+    self assert: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '[  ]') cursor:2 )).
+    self deny: (matcher searchStream: (SmallSense::TokenStream on: (Scanner for: '[ :hello') cursor:2 )).
+
+    "Created: / 15-05-2014 / 16:25:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TokenPatternParser.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,183 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Regex::RxParser subclass:#TokenPatternParser
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Utils-Matcher'
+!
+
+Regex::RxCharSetParser subclass:#TokenSpecParser
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:TokenPatternParser
+!
+
+!TokenPatternParser class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    A parser to parse token patterns
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!TokenPatternParser class methodsFor:'parsing'!
+
+parse: anArrayOrStream
+    ^ self new parse: anArrayOrStream
+
+    "Created: / 02-05-2014 / 18:56:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternParser methodsFor:'private'!
+
+characterSetFrom: setSpec
+        "<setSpec> is what goes between the brackets in a charset regex
+        (a String). Make a string containing all characters the spec specifies.
+        Spec is never empty."
+
+        | negated spec |
+        spec := ReadStream on: setSpec.
+        spec peek = $^
+                ifTrue:         [negated := true.
+                                spec next]
+                ifFalse:        [negated := false].
+        ^ TokenPatternTokenSet new
+                initializeElements: (TokenSpecParser on: spec) parse
+                negated: negated
+
+    "Created: / 09-05-2014 / 15:48:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+next
+    "Advance the input storing the just read character
+    as the lookahead."
+
+    "/ Overriden here to allow for spaces (to increase readability)
+
+    input atEnd ifTrue: [
+        lookahead := #epsilon.
+    ] ifFalse:[ 
+        input skipSeparators.
+        lookahead := input next
+    ].
+
+    "Created: / 09-05-2014 / 17:24:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternParser methodsFor:'recursive descent'!
+
+atom
+    | atom |
+
+    atom := super atom.
+    (atom isKindOf:Regex::RxsCharacter) ifTrue:[
+        atom := TokenPatternToken new type:atom character.
+    ].
+    ^ atom
+
+    "Created: / 09-05-2014 / 15:56:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternParser::TokenSpecParser methodsFor:'parsing'!
+
+parseNamedSet
+    | type value done out |
+
+    self
+        match:$[;
+        match:$:.
+    done := false.
+    out := '' writeStream.
+    [ done ] whileFalse:[ 
+        lookahead == $\ ifTrue:[ 
+            "/ Escape sequence
+            lookahead := source next.
+            out nextPut: lookahead.
+        ] ifFalse:[ 
+            lookahead == $: ifTrue:[ 
+                done := true.
+            ] ifFalse:[ 
+                lookahead == $= ifTrue:[ 
+                    type := out contents.
+                    out reset.
+                ] ifFalse:[ 
+                    out nextPut: lookahead.
+                ].
+            ].
+        ].
+        lookahead := source next.
+    ].
+    type isNil ifTrue:[ 
+        type := out contents.
+    ] ifFalse:[
+        value := out contents.
+    ].
+    self match:$].
+
+    elements add:((TokenPatternToken new)
+                type:type;
+                value:value)
+
+    "Modified: / 09-05-2014 / 16:35:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternParser class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TokenPatternToken.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,98 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Regex::RxsNode subclass:#TokenPatternToken
+	instanceVariableNames:'type value'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Utils-Matcher'
+!
+
+!TokenPatternToken class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!TokenPatternToken methodsFor:'accessing'!
+
+type
+    ^ type
+!
+
+type:something
+    type := something.
+!
+
+value
+    ^ value
+!
+
+value:something
+    value := something.
+! !
+
+!TokenPatternToken methodsFor:'double dispatch'!
+
+dispatchTo: matcher
+     "Inform the matcher of the kind of the node, and it
+      will do whatever it has to."
+
+     ^matcher syntaxToken: self
+
+    "Created: / 06-05-2014 / 14:32:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternToken methodsFor:'initialization'!
+
+initializeTyoe: t value: v
+    type := t.
+    value := v
+
+    "Created: / 02-05-2014 / 21:21:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenPatternToken methodsFor:'testing'!
+
+isEnumerable
+    ^ false
+
+    "Created: / 09-05-2014 / 16:10:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TokenPatternTokenSet.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,69 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Regex::RxsCharSet subclass:#TokenPatternTokenSet
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Utils-Matcher'
+!
+
+!TokenPatternTokenSet class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!TokenPatternTokenSet methodsFor:'accessing'!
+
+dispatchTo: aMatcher
+        "Inform the matcher of the kind of the node, and it
+        will do whatever it has to."
+
+        ^aMatcher syntaxTokenSet: self
+
+    "Created: / 09-05-2014 / 16:18:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+tokens
+    ^ elements
+
+    "Created: / 09-05-2014 / 16:20:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TokenStream.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,365 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#TokenStream
+	instanceVariableNames:'scanner scannerSourceReadLimit tokens last position full
+		positionMax positionOfCursor caretTokenReported'
+	classVariableNames:'BacklogSize'
+	poolDictionaries:''
+	category:'SmallSense-Utils-Matcher'
+!
+
+Object subclass:#Token
+	instanceVariableNames:'type value startPosition endPosition'
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:TokenStream
+!
+
+!TokenStream class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    A custom read-only stream that return high-level tokens produced
+    by underlying scanner object. The scanner must conform to API of
+    Scanner class.
+
+    Additionaly, when a cursor position is provided, TokenStream returns
+    a virtual token with type #CARET.
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+        Scanner
+        TokenPatternMatcher.
+
+"
+! !
+
+!TokenStream class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    BacklogSize := 100.
+
+    "Modified: / 07-08-2013 / 01:47:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenStream class methodsFor:'instance creation'!
+
+on: scanner
+    ^ self new initializeOn: scanner cursor: nil
+
+    "Created: / 06-05-2014 / 15:25:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-05-2014 / 15:08:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+on: scanner cursor: cursor
+    ^ self new initializeOn: scanner cursor: cursor
+
+    "Created: / 15-05-2014 / 15:08:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenStream methodsFor:'accessing'!
+
+sourceStream
+    ^ scanner sourceStream
+
+    "Created: / 07-08-2013 / 01:44:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenStream methodsFor:'initialization'!
+
+initializeOn: scannerObject
+    ^ self initializeOn: scannerObject cursor: nil
+
+    "Created: / 06-05-2014 / 15:27:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-05-2014 / 15:08:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+initializeOn: scannerArg cursor: positionOfCursorArg
+    scanner := scannerArg.
+    positionOfCursor := positionOfCursorArg.
+    tokens := Array new: BacklogSize.
+    last := 0.
+    full := false.
+    position := 0.
+    positionMax := 0.
+    caretTokenReported := false.
+
+    positionOfCursor notNil ifTrue:[ 
+        scannerArg sourceStream isExternalStream ifTrue:[ 
+            self error: 'Cursor reporting us supported only on internal streams'.
+        ].
+        scannerSourceReadLimit := scannerArg sourceStream readLimit.
+        scannerArg sourceStream readLimit: (positionOfCursor min: scannerSourceReadLimit)
+    ].
+
+    "Created: / 15-05-2014 / 15:07:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-05-2014 / 17:55:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenStream methodsFor:'stream api'!
+
+atEnd
+    ^ self peek type == #EOF
+
+    "Created: / 14-03-2012 / 22:53:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2013 / 01:49:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+contents
+    ^ Array streamContents:[ :s | 
+        [ self atEnd ] whileFalse:[ 
+            s nextPut: self next
+        ].
+    ].
+
+    "Created: / 15-05-2014 / 07:49:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+next
+    | i t |
+    position < positionMax ifTrue:[
+        i := last - (positionMax - position) + 1.
+        i <= 0 ifTrue:[
+            i := tokens size + i.
+        ].
+        position := position + 1.
+        ^ tokens at: i.
+    ].
+    scanner nextToken.
+    t := scanner token.
+    "/ Smalltalk / JavaScript scanners does not return token objects, sigh...
+    (t isCharacter or:[ t isString ]) ifTrue:[ 
+        t := Token new
+                type: scanner tokenType;
+                value: scanner token;
+                startPosition: scanner tokenStartPosition;
+                endPosition: scanner tokenEndPosition;        
+                yourself
+    ].
+    t isNil ifTrue:[ 
+        t := Token new
+                type: #EOF;
+                yourself
+    ].
+    t type == #EOF ifTrue:[ 
+        (caretTokenReported not and:[scanner sourceStream position == positionOfCursor]) ifTrue:[ 
+            t type: #CARET.
+            t value: $|.
+            t startPosition: positionOfCursor.
+            t endPosition: positionOfCursor.
+            caretTokenReported := true.
+            scanner sourceStream readLimit: scannerSourceReadLimit.
+        ].
+    ].
+    position := positionMax := positionMax + 1.
+    last := last + 1.
+    last > tokens size ifTrue:[ 
+        full ifFalse:[ full := true ].
+        last := 1 
+    ].
+    tokens at: last put: t.
+    ^ t
+
+    "Created: / 14-03-2012 / 22:53:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-05-2014 / 17:56:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+next: anInteger 
+    "Answer up to anInteger elements of my collection. Overridden for efficiency."
+
+    ^ self shouldNotImplement
+
+    "Modified: / 06-05-2014 / 15:51:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+peek
+    | t |
+
+    t := self next.
+    position := position - 1.
+    ^ t
+
+    "Modified: / 07-08-2013 / 01:12:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+position
+    ^position
+
+    "Created: / 14-03-2012 / 22:52:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2013 / 01:06:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+position: anInteger
+    (positionMax - anInteger) > (tokens size) ifTrue:[
+        Stream positionErrorSignal raiseErrorString:'Not that much tokens in backlog!! You may try to increase it.'.
+        ^ self.
+    ].
+    position := anInteger.
+
+    "Modified: / 07-08-2014 / 11:46:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+position: tokenPosition sourcePosition: sourcePosition
+    position := positionMax := tokenPosition.
+    tokens := tokens class new: tokens size.
+    full := false.
+
+    scanner sourceStream position: sourcePosition.
+    positionOfCursor notNil ifTrue:[
+        sourcePosition < positionOfCursor ifTrue:[
+            scanner sourceStream readLimit: (positionOfCursor min: scannerSourceReadLimit).
+            caretTokenReported := false.
+        ].
+    ].
+
+    "Created: / 13-06-2014 / 17:06:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+reset
+    (positionMax) > (tokens size) ifTrue:[
+        scanner sourceStream reset.    
+        tokens := Array new: BacklogSize.
+        last := 0.
+        full := false.
+        position := 0.
+        positionMax := 0.
+    ].
+    position := 0.
+
+    "Created: / 14-05-2014 / 16:19:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 11:57:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+skipSeparators
+    self halt.
+
+    "Created: / 15-03-2012 / 10:35:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2013 / 01:15:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+uncheckedPeek
+    "An unchecked version of peek that throws an error if we try to peek over the end of the stream, even faster than #peek."
+
+    ^ self peek
+
+    "Modified: / 14-03-2012 / 22:46:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenStream::Token methodsFor:'accessing'!
+
+endPosition
+    ^ endPosition
+!
+
+endPosition:something
+    endPosition := something.
+!
+
+startPosition
+    ^ startPosition
+!
+
+startPosition:something
+    startPosition := something.
+!
+
+stopPosition
+    ^ endPosition
+
+    "Created: / 04-04-2013 / 00:32:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+type
+    ^ type
+!
+
+type:something
+    type := something.
+!
+
+value
+    ^ value
+!
+
+value:something
+    value := something.
+! !
+
+!TokenStream::Token methodsFor:'printing & storing'!
+
+printOn:aStream
+    "append a printed representation if the receiver to the argument, aStream"
+
+    aStream nextPut: ${.
+    type printOn:aStream.
+    aStream nextPutAll:' - '.
+    value printOn:aStream.
+    aStream nextPutAll:' <'.
+    startPosition printOn:aStream.
+    aStream nextPutAll:'-'.
+    endPosition printOn:aStream.
+    aStream nextPutAll:'>}'.
+
+    "Modified: / 06-05-2014 / 15:33:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TokenStream class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
+
+TokenStream initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__Type.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,262 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#Type
+	instanceVariableNames:''
+	classVariableNames:'ObjectType'
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types'
+!
+
+!Type class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    An object representing an inferred type.
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!Type class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    ObjectType := ClassType new klass: Object
+
+    "Modified: / 16-12-2011 / 02:23:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type class methodsFor:'instance creation'!
+
+default
+
+    <resource: #obsolete>
+
+    ^self unknown
+
+    "Created: / 26-11-2011 / 16:40:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+unknown
+
+    ^TypeHolder with: UnknownType new
+
+    "Created: / 16-12-2011 / 09:42:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+withClass: aClass
+    self assert: aClass notNil.
+
+    ^TypeHolder with: (ClassType new klass: aClass)
+
+    "Created: / 26-11-2011 / 14:14:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-10-2013 / 14:11:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type methodsFor:'accessing'!
+
+trustfullness
+    "Return an integer value in <1..100>, higher value
+     means the object is more likely of that type."
+
+    ^self subclassResponsibility
+
+    "Created: / 17-05-2012 / 19:20:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullness: anInteger
+    "Set the trustfullness"
+
+    ^self subclassResponsibility
+
+    "Created: / 17-05-2012 / 19:43:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullnessAdd: anInteger 
+    "Advance mu trustfullness by an Integer"
+
+    self trustfullness: self trustfullness + anInteger
+
+    "Created: / 17-05-2012 / 19:46:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type methodsFor:'comparing'!
+
+= another
+
+    ^self subclassResponsibility
+
+    "Created: / 16-12-2011 / 13:35:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hash
+
+    ^self subclassResponsibility
+
+    "Created: / 16-12-2011 / 13:35:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type methodsFor:'enumerating'!
+
+classes
+    "Return set of all classes that this type represents"
+
+    ^ OrderedCollection streamContents:[:s| self classesDo:[:cls|s nextPut: cls] ].
+
+    "Created: / 04-10-2013 / 13:20:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+classesDo: aBlock
+    "Enumerate all classes that this type represents"
+
+    self subclassResponsibility
+
+    "Created: / 16-12-2011 / 13:33:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+typesDo: aBlock
+
+    aBlock value: self
+
+    "Created: / 16-12-2011 / 02:16:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type methodsFor:'operations'!
+
+classSide
+
+    ^self subclassResponsibility
+
+    "Created: / 16-12-2011 / 13:20:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+instanceSide
+
+    ^self subclassResponsibility
+
+    "Created: / 16-12-2011 / 13:20:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+union: anotherType
+
+    ^UnionType new
+        addType: self;
+        addType: anotherType;
+        yourself
+
+    "Created: / 16-12-2011 / 02:00:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type methodsFor:'printing & storing'!
+
+printOn:aStream
+
+    aStream nextPut:$<; space.
+    self printWithoutAnglesOn: aStream.
+    aStream space; nextPut:$>.
+
+    "Modified: / 24-09-2013 / 13:47:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+printWithoutAnglesOn: aStream
+
+    self subclassResponsibility
+
+    "Created: / 16-12-2011 / 01:45:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type methodsFor:'testing'!
+
+isClassType
+
+    ^false
+
+    "Created: / 16-12-2011 / 02:00:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isTypeHolder
+
+    ^false
+
+    "Created: / 16-12-2011 / 02:05:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isUnionType
+
+    ^false
+
+    "Created: / 16-12-2011 / 02:00:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isUnknownType
+
+    ^false
+
+    "Created: / 16-12-2011 / 13:29:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Type class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
+
+Type initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__TypeHolder.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,219 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#TypeHolder
+	instanceVariableNames:'type'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types'
+!
+
+!TypeHolder class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!TypeHolder class methodsFor:'instance creation'!
+
+with: aSmallSenseType
+
+    ^self new type: aSmallSenseType; yourself
+
+    "Created: / 16-12-2011 / 01:42:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TypeHolder methodsFor:'accessing'!
+
+trustfullness
+    ^type trustfullness
+
+    "Created: / 17-05-2012 / 19:50:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullness:aSmallInteger
+    type trustfullness:aSmallInteger
+
+    "Created: / 17-05-2012 / 19:50:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullnessAdd: anInteger
+    type trustfullnessAdd: anInteger
+
+    "Created: / 17-05-2012 / 19:50:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+type
+    ^ type
+!
+
+type:aSmallSenseType
+
+    self assert: aSmallSenseType isTypeHolder not.
+    type := aSmallSenseType.
+
+    "Modified: / 16-12-2011 / 02:12:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TypeHolder methodsFor:'adding & removing'!
+
+addClass: aClass
+
+    self type: (type union: (ClassType new klass: aClass)).
+
+    "Created: / 26-11-2011 / 14:04:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addClasses: aCollection
+
+    | union |
+    union := UnionType new.
+    union addType: type.
+    union addTypes: (aCollection collect: [:c|ClassType new klass:c]).
+    self type: union
+
+    "Created: / 26-11-2011 / 14:04:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TypeHolder methodsFor:'enumerating'!
+
+classes
+    ^ type classes
+
+    "Created: / 04-10-2013 / 13:20:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+classesDo: aBlock
+
+    type classesDo: aBlock
+
+    "Created: / 16-12-2011 / 13:34:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+typesDo: aBlock
+
+    type typesDo: aBlock
+
+    "Created: / 16-12-2011 / 02:17:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TypeHolder methodsFor:'operations'!
+
+classSide
+
+    ^self class with: type classSide
+
+    "Created: / 16-12-2011 / 13:24:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+instanceSide
+
+    ^self class with: type instanceSide
+
+    "Created: / 16-12-2011 / 13:24:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+union: anotherType
+
+    self type: (type union: anotherType)
+
+    "Created: / 16-12-2011 / 02:18:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-09-2013 / 02:30:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TypeHolder methodsFor:'printing & storing'!
+
+printOn:aStream
+    "append a printed representation if the receiver to the argument, aStream"
+
+    type printOn: aStream
+
+    "Modified: / 16-12-2011 / 01:46:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+printWithoutAnglesOn: aStream
+
+    self subclassResponsibility
+
+    "Created: / 16-12-2011 / 01:45:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TypeHolder methodsFor:'testing'!
+
+isClassType
+
+    ^type isClassType
+
+    "Created: / 16-12-2011 / 02:00:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-07-2013 / 13:08:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isTypeHolder
+
+    ^true
+
+    "Created: / 16-12-2011 / 02:05:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isUnionType
+
+    ^type isUnionType
+
+    "Created: / 16-12-2011 / 02:00:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-07-2013 / 13:09:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isUnknownType
+
+    ^type isUnknownType
+
+    "Created: / 24-07-2013 / 13:09:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!TypeHolder class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__UnionType.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,306 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Type subclass:#UnionType
+	instanceVariableNames:'types trustfullness trustfullnessBonus'
+	classVariableNames:''
+	poolDictionaries:'SmallSense::SmalltalkInferencerParameters'
+	category:'SmallSense-Smalltalk-Types'
+!
+
+!UnionType class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!UnionType methodsFor:'accessing'!
+
+trustfullness
+    "Return an integer value in <1..100>, higher value
+     means the object is more likely of that type."
+
+    trustfullness isNil ifTrue:[
+        self updateTrustfullness
+    ].
+    ^ trustfullness
+
+    "Modified: / 18-09-2013 / 01:16:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullness: anInteger
+    "Remember the bonus/malus given by an inferences"
+
+    trustfullnessBonus := anInteger - trustfullness.
+    trustfullness := anInteger min: 100.
+
+    "Created: / 17-05-2012 / 19:43:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullnessAdd: anInteger
+
+    trustfullnessBonus := (trustfullnessBonus ? 0) + anInteger.
+    trustfullness := trustfullness + anInteger.
+
+    "Created: / 17-05-2012 / 19:47:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+types
+    ^ types ? #()
+
+    "Modified: / 16-12-2011 / 02:01:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+types:something
+    types := something.
+    self updateTrustfullness
+
+    "Modified: / 17-05-2012 / 19:23:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'adding & removing'!
+
+addType: typeOrHolder
+
+   self basicAddType: typeOrHolder.
+   self prune
+
+    "Created: / 16-12-2011 / 01:50:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addTypes: typeOrHolder
+
+   self basicAddTypes: typeOrHolder.
+   self prune
+
+    "Created: / 16-12-2011 / 01:51:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'adding & removing-private'!
+
+basicAddType: typeOrHolder
+
+    | type |
+    typeOrHolder isTypeHolder ifTrue:[
+        type := typeOrHolder type
+    ] ifFalse:[
+        type := typeOrHolder
+    ].
+
+    types isNil ifTrue:[types := OrderedCollection new].
+    type isUnionType ifTrue:[
+        self basicAddTypes: type types.
+    ] ifFalse:[
+        type isUnknownType ifFalse:[
+            | existing |
+
+            existing := types detect:[:each | each = type ] ifNone:[nil].
+            existing isNil ifTrue:[
+                types add: type.
+            ] ifFalse:[
+                existing trustfullness: (existing trustfullness max: type trustfullness)
+            ]
+        ]
+    ].
+
+    "Created: / 17-05-2012 / 19:27:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-09-2013 / 01:14:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+basicAddTypes: someTypes
+
+    someTypes do:[:each|self basicAddType: each ].
+
+    "Created: / 17-05-2012 / 19:28:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'comparing'!
+
+= another
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^self class == another class 
+        and:[types size == another types size 
+            and:[types = another types]]
+
+    "Modified: / 16-12-2011 / 13:38:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hash
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^types hash
+
+    "Modified: / 16-12-2011 / 13:39:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'enumerating'!
+
+classesDo:aBlock
+    "Enumerate all classes that this type represents"
+
+    types notNil ifTrue:[
+        ^types do:[:t|t classesDo: aBlock]    
+    ].
+
+    "Modified: / 16-12-2011 / 13:34:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+typesDo: aBlock
+
+    (types ? #()) do:[:each|
+        each typesDo: aBlock
+    ].
+
+    "Created: / 16-12-2011 / 02:17:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'operations'!
+
+classSide
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ self class new 
+        types: (types ? #() collect:[:t|t classSide])
+
+    "Modified: / 16-12-2011 / 13:22:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+instanceSide
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ self class new 
+        types: (types ? #() collect:[:t|t instanceSide])
+
+    "Modified: / 16-12-2011 / 13:22:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'printing & storing'!
+
+printWithoutAnglesOn:aStream
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    types isNil ifTrue:[ 
+        aStream nextPut: $?
+    ] ifFalse:[
+        types 
+            do:[:each|each printWithoutAnglesOn:aStream]
+            separatedBy:[aStream space; nextPut:$|; space.]
+    ]
+
+    "Modified: / 24-09-2013 / 13:47:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'private'!
+
+prune
+    "Prune the types - remove less likely types."
+
+    self updateTrustfullness.   
+    types size < 1 ifTrue:[ ^ self ].
+
+    "Experimental - remove those with trustfullness less than mine"    
+    types := types reject:[:type|type trustfullness < trustfullness ].      
+
+
+    (UnionTypeReduceThreshold notNil or:[types size > UnionTypeMaxSize]) ifTrue:[
+        "/ Try to find common superclass...
+        types size > (UnionTypeReduceThreshold ? 5) ifTrue:[
+            | reduced |    
+            reduced := types reduce:[ :a :b | ClassType new klass: (a klass commonSuperclass: b klass)].
+            ((reduced klass ~~ Object) and:[reduced klass ~~ Object class]) ifTrue:[ 
+                types  := OrderedCollection with: reduced. 
+            ] ifFalse:[ 
+                "/ If the size of types exeeds limit, make it Object anyway.
+                types size > UnionTypeMaxSize ifTrue:[ 
+                    types  := OrderedCollection with: reduced. 
+                ].
+            ].
+        ].     
+    ].
+
+    "Created: / 17-05-2012 / 19:38:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-03-2014 / 23:28:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateTrustfullness
+    "Recompute the trustfullness, This is subject to tuning"
+    "Average if individual types"
+    
+    types isEmpty ifTrue: [
+        trustfullness := 1
+    ] ifFalse: [
+        trustfullness := (types inject: 0
+                into: [:a :type | a + type trustfullness ]) / types size.
+        trustfullness := trustfullness + (trustfullnessBonus ? 0).
+    ].
+
+    "Created: / 17-05-2012 / 19:22:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 18-09-2013 / 01:08:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType methodsFor:'testing'!
+
+isUnionType
+
+    ^true
+
+    "Created: / 16-12-2011 / 02:01:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isUnknownType
+    "Union type is consireded unknown iff types are empty or all
+     unknown"
+
+    ^types isEmptyOrNil or:[types allSatisfy:[:t|t isUnknownType]]
+
+    "Created: / 24-07-2013 / 13:07:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnionType class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__UnknownType.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,186 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+Type subclass:#UnknownType
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Smalltalk-Types'
+!
+
+UnknownType class instanceVariableNames:'theOneAndOnlyInstance'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+!UnknownType class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!UnknownType class methodsFor:'instance creation'!
+
+flushSingleton
+    "flushes the cached singleton"
+
+    theOneAndOnlyInstance := nil
+
+    "
+     self flushSingleton
+    "
+!
+
+new
+    "returns a singleton"
+
+    ^ self theOneAndOnlyInstance.
+!
+
+theOneAndOnlyInstance
+    "returns a singleton"
+
+    theOneAndOnlyInstance isNil ifTrue:[
+        theOneAndOnlyInstance := self basicNew initialize.
+    ].
+    ^ theOneAndOnlyInstance.
+! !
+
+!UnknownType methodsFor:'accessing'!
+
+trustfullness
+    "Return an integer value in <1..100>, higher value
+     means the object is more likely of that type."
+
+    ^ 1
+
+    "Modified: / 17-05-2012 / 19:20:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+trustfullness: anInteger
+    "Nothing to do here"
+
+    "Created: / 17-05-2012 / 19:44:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnknownType methodsFor:'comparing'!
+
+= another
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^self == another
+
+    "Modified: / 16-12-2011 / 13:37:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+hash
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ self identityHash
+
+    "Modified: / 16-12-2011 / 13:37:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnknownType methodsFor:'enumerating'!
+
+classesDo:aBlock
+    "Enumerate all classes that this type represents"
+
+    ^ aBlock value: Object
+
+    "Modified: / 16-12-2011 / 13:34:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnknownType methodsFor:'operations'!
+
+classSide
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ self class new
+
+    "Modified: / 16-12-2011 / 13:21:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+instanceSide
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ self class new
+
+    "Modified: / 16-12-2011 / 13:21:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+union: anotherType
+
+    ^anotherType
+
+    "Created: / 16-12-2011 / 02:20:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnknownType methodsFor:'printing & storing'!
+
+printWithoutAnglesOn:aStream
+    "superclass SmallSenseType says that I am responsible to implement this method"
+
+    ^ aStream nextPut:$?
+
+    "Modified: / 16-12-2011 / 02:19:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnknownType methodsFor:'testing'!
+
+isUnknownType
+
+    ^true
+
+    "Created: / 16-12-2011 / 13:29:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UnknownType class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__VariableBindingPO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,87 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#VariableBindingPO
+	instanceVariableNames:'binding'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Java-Interface-PO'
+!
+
+!VariableBindingPO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!VariableBindingPO methodsFor:'accessing'!
+
+binding
+    ^ binding
+!
+
+binding:b
+    binding := b.
+!
+
+label
+    "Return a text to be displayed. The label may be cached
+     `label` instvar."
+
+    ^ binding name
+
+    "Created: / 14-08-2014 / 09:02:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage:aProgrammingLanguage
+    "Answers a string to complete"
+
+    ^ binding name
+
+    "Created: / 14-08-2014 / 09:02:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VariableBindingPO methodsFor:'testing'!
+
+isSmallSenseVariableBindingPO
+    ^ true
+
+    "Created: / 14-08-2014 / 09:01:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__VariablePO.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,206 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+PO subclass:#VariablePO
+	instanceVariableNames:'class type name'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'SmallSense-Core-Interface-PO'
+!
+
+!VariablePO class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License. 
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+! !
+
+!VariablePO class methodsFor:'instance creation'!
+
+argument: name
+
+    ^self new name: name; type: #MethodArg
+
+    "Created: / 26-11-2011 / 18:45:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+classVariable: name in: class
+
+    ^self new name: name; type: #ClassVar; class: class
+
+    "Created: / 26-11-2011 / 18:46:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+globalVariable: name
+
+    ^self new name: name; type: #Global
+
+    "Created: / 26-11-2011 / 18:57:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+instanceVariable: name in: class
+
+    ^self new name: name; type: #InstanceVar; class: class
+
+    "Created: / 26-11-2011 / 18:45:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+variable: name
+
+    ^self new name: name; type: #MethodVar
+
+    "Created: / 26-11-2011 / 18:45:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VariablePO methodsFor:'accessing'!
+
+class:something
+    class := something.
+
+    "Created: / 06-04-2011 / 16:51:42 / Jakub <zelenja7@fel.cvut.cz>"
+!
+
+label
+    ^ name
+
+    "Created: / 20-05-2014 / 11:30:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+name
+    ^ name
+
+    "Created: / 20-05-2014 / 11:38:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+name: aString
+    name := aString
+
+    "Created: / 20-05-2014 / 11:37:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+stringToCompleteForLanguage:aProgrammingLanguage
+    "Answers a string to complete"
+
+    ^ name
+
+    "Created: / 20-05-2014 / 11:33:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+type:something
+    type := something.
+! !
+
+!VariablePO methodsFor:'accessing-private'!
+
+subject
+    "Return the real object for which the receiver
+     is a presentor.
+     
+     For internal usage only."
+
+    ^ name
+
+    "Created: / 20-06-2014 / 11:11:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VariablePO methodsFor:'displaying'!
+
+displayLabel:aLabel h:lH on:aGC x:x y:y h:h isHighlightedAsSelected: highlighted
+    | lw cn cnw fg y0 |
+
+    super displayLabel:aLabel h:lH on:aGC x:x y:y h:h isHighlightedAsSelected: highlighted.
+
+    class isNil ifTrue:[ ^ self ]. "/ Could be pseudo-variable
+
+    lw :=  x + (parent isNil ifTrue:[IconWidth] ifFalse:[0]) + (self label widthOn: aGC).
+    cn := class nameWithoutPrefix.
+    cnw := aGC widthOfString: cn.
+    y0 := y - (lH + 1 - h // 2).
+    y0 := y0 + (cn ascentOn:aGC).  
+
+    (aGC width > (lw + cnw + 5)) ifTrue:
+        [fg := aGC paint.
+        aGC paint: Color gray .
+        aGC displayString: cn x: aGC width - cnw - 5 y: y0.
+        aGC paint: fg.
+    ]
+
+    "Created: / 03-02-2015 / 05:34:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-04-2014 / 00:24:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+displayOn:aGC x:x y:y opaque:opaque
+
+    | lw cn cnw fg |
+
+    super displayOn:aGC x:x y:y opaque:opaque.
+
+    class isNil ifTrue:[^self].
+
+    lw :=  x + 16 + (self label widthOn: aGC).
+    cn := class nameWithoutPrefix.
+    cnw := aGC widthOfString: cn.
+
+    (aGC width > (lw + cnw + 5)) ifTrue:
+        [fg := aGC paint.
+        aGC paint: Color gray .
+        aGC displayString: cn x: aGC width - cnw - 5 y: y.
+        aGC paint: fg.
+    ]
+
+    "Created: / 21-05-2011 / 11:02:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (format): / 17-09-2013 / 23:39:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VariablePO methodsFor:'testing'!
+
+isSmallSenseVariablePO
+    ^ true
+! !
+
+!VariablePO class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id$'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/abbrev.stc	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,97 @@
+# automagically generated by the project definition
+# this file is needed for stc to be able to compile modules independently.
+# it provides information about a classes filename, category and especially namespace.
+SmallSense::AbstractDIalog SmallSense__AbstractDIalog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::AbstractSearchProcessor SmallSense__AbstractSearchProcessor stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::AbstractTestCase SmallSense__AbstractTestCase stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::CodeHighlightingService SmallSense__CodeHighlightingService stx:goodies/smallsense 'SmallSense-Core-Services' 0
+SmallSense::CodeNavigationService SmallSense__CodeNavigationService stx:goodies/smallsense 'SmallSense-Core-Services' 0
+SmallSense::CompletionContext SmallSense__CompletionContext stx:goodies/smallsense 'SmallSense-Core' 0
+SmallSense::CompletionController SmallSense__CompletionController stx:goodies/smallsense 'SmallSense-Core' 0
+SmallSense::CompletionEngine SmallSense__CompletionEngine stx:goodies/smallsense 'SmallSense-Core' 0
+SmallSense::CompletionResult SmallSense__CompletionResult stx:goodies/smallsense 'SmallSense-Core' 0
+SmallSense::CompletionView SmallSense__CompletionView stx:goodies/smallsense 'SmallSense-Core-Interface' 2
+SmallSense::CriticsWindow SmallSense__CriticsWindow stx:goodies/smallsense 'SmallSense-Core-Interface' 1
+SmallSense::EditService SmallSense__EditService stx:goodies/smallsense 'SmallSense-Core-Services' 0
+SmallSense::EditSupport SmallSense__EditSupport stx:goodies/smallsense 'SmallSense-Core-Services' 0
+SmallSense::Info SmallSense__Info stx:goodies/smallsense 'SmallSense-Smalltalk-Types-Info' 0
+SmallSense::Manager SmallSense__Manager stx:goodies/smallsense 'SmallSense-Smalltalk-Types-Info' 0
+SmallSense::NavigatorStep SmallSense__NavigatorStep stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 0
+SmallSense::PO SmallSense__PO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::ParseTreeIndex SmallSense__ParseTreeIndex stx:goodies/smallsense 'SmallSense-Core-Index' 0
+SmallSense::ParseTreeIndexEntry SmallSense__ParseTreeIndexEntry stx:goodies/smallsense 'SmallSense-Core-Index' 0
+SmallSense::ParseTreeInspector SmallSense__ParseTreeInspector stx:goodies/smallsense 'SmallSense-Core-Interface' 1
+SmallSense::SelectorNode SmallSense__SelectorNode stx:goodies/smallsense 'SmallSense-Smalltalk' 0
+SmallSense::SettingsAppl SmallSense__SettingsAppl stx:goodies/smallsense 'SmallSense-Core-Interface' 1
+SmallSense::SmalltalkChecker SmallSense__SmalltalkChecker stx:goodies/smallsense 'SmallSense-Smalltalk-Lint' 0
+SmallSense::SmalltalkInferencerParameters SmallSense__SmalltalkInferencerParameters stx:goodies/smallsense 'SmallSense-Smalltalk-Types-Inference' 0
+SmallSense::SmalltalkLintService SmallSense__SmalltalkLintService stx:goodies/smallsense 'SmallSense-Smalltalk-Lint' 0
+SmallSense::SmalltalkParseNodeVisitor SmallSense__SmalltalkParseNodeVisitor stx:goodies/smallsense 'SmallSense-Smalltalk' 0
+SmallSense::SmalltalkParser SmallSense__SmalltalkParser stx:goodies/smallsense 'SmallSense-Smalltalk' 3
+SmallSense::SmalltalkQuickFixer SmallSense__SmalltalkQuickFixer stx:goodies/smallsense 'SmallSense-Smalltalk-Lint' 0
+SmallSense::SmalltalkSyntaxHighlighter SmallSense__SmalltalkSyntaxHighlighter stx:goodies/smallsense 'SmallSense-Smalltalk' 3
+SmallSense::SmalltalkUnacceptedMethodEnvironment SmallSense__SmalltalkUnacceptedMethodEnvironment stx:goodies/smallsense 'SmallSense-Smalltalk-Lint' 0
+SmallSense::TokenPatternMatcher SmallSense__TokenPatternMatcher stx:goodies/smallsense 'SmallSense-Utils-Matcher' 0
+SmallSense::TokenPatternParser SmallSense__TokenPatternParser stx:goodies/smallsense 'SmallSense-Utils-Matcher' 0
+SmallSense::TokenPatternToken SmallSense__TokenPatternToken stx:goodies/smallsense 'SmallSense-Utils-Matcher' 0
+SmallSense::TokenPatternTokenSet SmallSense__TokenPatternTokenSet stx:goodies/smallsense 'SmallSense-Utils-Matcher' 0
+SmallSense::TokenStream SmallSense__TokenStream stx:goodies/smallsense 'SmallSense-Utils-Matcher' 0
+SmallSense::Type SmallSense__Type stx:goodies/smallsense 'SmallSense-Smalltalk-Types' 0
+SmallSense::TypeHolder SmallSense__TypeHolder stx:goodies/smallsense 'SmallSense-Smalltalk-Types' 0
+stx_goodies_smallsense stx_goodies_smallsense stx:goodies/smallsense '* Projects & Packages *' 3
+SmallSense::AbstractJavaCompletionEngine SmallSense__AbstractJavaCompletionEngine stx:goodies/smallsense 'SmallSense-Java' 0
+SmallSense::AbstractListDialog SmallSense__AbstractListDialog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::ClassInfo SmallSense__ClassInfo stx:goodies/smallsense 'SmallSense-Smalltalk-Types-Info' 0
+SmallSense::ClassPO SmallSense__ClassPO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::ClassSearchProcessor SmallSense__ClassSearchProcessor stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::ClassType SmallSense__ClassType stx:goodies/smallsense 'SmallSense-Smalltalk-Types' 0
+SmallSense::CompositeProcessor SmallSense__CompositeProcessor stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::ConstantPO SmallSense__ConstantPO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::EditSupportTests SmallSense__EditSupportTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::GenericEditSupport SmallSense__GenericEditSupport stx:goodies/smallsense 'SmallSense-Core-Services' 0
+SmallSense::ImplementorSearchProcessor SmallSense__ImplementorSearchProcessor stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::JavaEditSupport SmallSense__JavaEditSupport stx:goodies/smallsense 'SmallSense-Java' 0
+SmallSense::JavaImportPO SmallSense__JavaImportPO stx:goodies/smallsense 'SmallSense-Java-Interface-PO' 0
+SmallSense::MethodBindingPO SmallSense__MethodBindingPO stx:goodies/smallsense 'SmallSense-Java-Interface-PO' 0
+SmallSense::MethodInfo SmallSense__MethodInfo stx:goodies/smallsense 'SmallSense-Smalltalk-Types-Info' 0
+SmallSense::MethodPO SmallSense__MethodPO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::PackagePO SmallSense__PackagePO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::PluggablePO SmallSense__PluggablePO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::PluggableSearchProcessor SmallSense__PluggableSearchProcessor stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::SmalltalkCompletionEngine SmallSense__SmalltalkCompletionEngine stx:goodies/smallsense 'SmallSense-Smalltalk' 0
+SmallSense::SmalltalkEditSupport SmallSense__SmalltalkEditSupport stx:goodies/smallsense 'SmallSense-Smalltalk' 0
+SmallSense::SmalltalkInferencer SmallSense__SmalltalkInferencer stx:goodies/smallsense 'SmallSense-Smalltalk-Types-Inference' 0
+SmallSense::SmalltalkParseNodeFinder SmallSense__SmalltalkParseNodeFinder stx:goodies/smallsense 'SmallSense-Smalltalk' 0
+SmallSense::SnippetPO SmallSense__SnippetPO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::UnionType SmallSense__UnionType stx:goodies/smallsense 'SmallSense-Smalltalk-Types' 0
+SmallSense::UnknownType SmallSense__UnknownType stx:goodies/smallsense 'SmallSense-Smalltalk-Types' 1
+SmallSense::VariableBindingPO SmallSense__VariableBindingPO stx:goodies/smallsense 'SmallSense-Java-Interface-PO' 0
+SmallSense::VariablePO SmallSense__VariablePO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::AbstractJavaCompletionEngineSimple SmallSense__AbstractJavaCompletionEngineSimple stx:goodies/smallsense 'SmallSense-Java' 2
+SmallSense::AbstractSearchDialog SmallSense__AbstractSearchDialog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 2
+SmallSense::AbstractSelectDialog SmallSense__AbstractSelectDialog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::GroovyEditSupport SmallSense__GroovyEditSupport stx:goodies/smallsense 'SmallSense-Groovy' 0
+SmallSense::JavaCompletionEngine SmallSense__JavaCompletionEngine stx:goodies/smallsense 'SmallSense-Java' 0
+SmallSense::JavaConstructorPO SmallSense__JavaConstructorPO stx:goodies/smallsense 'SmallSense-Java-Interface-PO' 0
+SmallSense::MethodKeywordRestPO SmallSense__MethodKeywordRestPO stx:goodies/smallsense 'SmallSense-Core-Interface-PO' 0
+SmallSense::SmalltalkEditSupportTests SmallSense__SmalltalkEditSupportTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::ClassSearchDialog SmallSense__ClassSearchDialog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 2
+SmallSense::JavaCompletionEngineSimple SmallSense__JavaCompletionEngineSimple stx:goodies/smallsense 'SmallSense-Java' 2
+SmallSense::MethodSearchDialog SmallSense__MethodSearchDialog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 2
+SmallSense::Navigator SmallSense__Navigator stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 2
+SmallSense::PackageSelectDialog SmallSense__PackageSelectDialog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::ProtocolSelectDialog SmallSense__ProtocolSelectDialog stx:goodies/smallsense 'SmallSense-Core-Interface-Search' 1
+SmallSense::GroovyCompletionEngineSimple SmallSense__GroovyCompletionEngineSimple stx:goodies/smallsense 'SmallSense-Groovy' 2
+SmallSense::AbstractJavaCompletionEngineTests SmallSense__AbstractJavaCompletionEngineTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::BaseTestClass SmallSense__BaseTestClass stx:goodies/smallsense 'SmallSense-Tests-Obsolete' 1
+SmallSense::CompletionEngineTests SmallSense__CompletionEngineTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::FinderTests SmallSense__FinderTests stx:goodies/smallsense 'SmallSense-Tests-Obsolete' 1
+SmallSense::GroovyCompletionEngineSimpleTests SmallSense__GroovyCompletionEngineSimpleTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::JavaCompletionEngineEnvironmentResource SmallSense__JavaCompletionEngineEnvironmentResource stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::JavaCompletionEngineTests SmallSense__JavaCompletionEngineTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::JavaEditSupportTests SmallSense__JavaEditSupportTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::RecognizerTests SmallSense__RecognizerTests stx:goodies/smallsense 'SmallSense-Tests-Obsolete' 1
+SmallSense::SmalltalkCompletionEngineTests SmallSense__SmalltalkCompletionEngineTests stx:goodies/smallsense 'SmallSense-Tests' 1
+SmallSense::SmalltalkParserTests SmallSense__SmalltalkParserTests stx:goodies/smallsense 'SmallSense-Tests-Obsolete' 1
+SmallSense::TestCase SmallSense__TestCase stx:goodies/smallsense 'SmallSense-Tests-Obsolete' 1
+SmallSense::TokenPatternMatcherTests SmallSense__TokenPatternMatcherTests stx:goodies/smallsense 'SmallSense-Tests' 1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/autopackage/default.apspec	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,85 @@
+# -*- shell-script -*-
+[Meta]
+ShortName: 
+SoftwareVersion: 6.2.1.1
+DisplayName: Smalltalk/X Class library
+RootName: @exept.de/expecco:$SOFTWAREVERSION
+Summary: Smalltalk/X Class library
+Maintainer: eXept Software AG
+Packager: eXept Software AG
+PackageVersion: 1
+CPUArchitectures: x86
+AutopackageTarget: 1.0
+Type: Library
+License: Commercial
+
+[Description]
+Smalltalk/X Class library
+
+[BuildPrepare]
+# If you're using autotools, the default should be enough.
+# prepareBuild will set up apbuild and run configure for you. If you
+# need to pass arguments to configure, just add them to prepareBuild:
+# prepareBuild --enable-foo --disable-bar
+#prepareBuild
+
+[BuildUnprepare]
+# If you're using prepareBuild above, there is no need to change this!
+#unprepareBuild
+
+[Globals]
+# Variables declared in this section will be available in all other sections
+export APKG_BUILD_SKIP_CONFIGURE=1
+export APKG_BUILD_SKIP_MAKE=1
+export MYPREFIX=/opt/
+
+[Prepare]
+#recommend '@autopackage.org/autopackage-gtk' 1
+
+[Imports]
+import <<EOF
+$source_dir/
+$source_dir/resources
+$source_dir/keyboard.rc
+$source_dir/display.rc
+$source_dir/../doc
+$source_dir/../testsuites/webedition
+$source_dir/../projects/libraries
+$source_dir/../reportGenerator/tools
+$source_dir/../../pdf/afm
+$source_dir/../plugin/selenium/libexept_expecco_plugin_selenium.so
+$source_dir/../externalTools
+EOF
+
+for i in $source_dir/*.so
+do
+    echo $source_dir/$(readlink $i)
+done | import
+
+[Install]
+if [ "$PREFIX" != "/usr" ]
+then
+    export MYPREFIX=$PREFIX
+fi
+
+find . -type d \( -name CVS -or -name 'not_*' \) -print | xargs rm -rf
+mkdir -p $MYPREFIX
+copyFiles expecco *.rc resources        $MYPREFIX/bin
+copyFiles *.so                          $MYPREFIX/lib
+copyFiles doc externalTools             $MYPREFIX/packages/exept/expecco
+copyFiles webedition/projects libraries $MYPREFIX/testsuites
+copyFiles tools                         $MYPREFIX/packages/exept/expecco/reportGenerator
+copyFiles afm                           $MYPREFIX/packages/exept/pdf
+copyFiles libexept_expecco_plugin_selenium.so   $MYPREFIX/plugin
+
+#installExe expecco
+#installLib *.so
+#installData resources
+#installData keyboard.rc
+#installData doc
+
+[Uninstall]
+# Leaving this at the default is safe unless you use custom commands in
+# "Install" to create files. All autopackage API functions
+# that installs files are logged.
+uninstallFromLog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bc.mak	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,176 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense.
+#
+# Warning: once you modify this file, do not rerun
+# stmkmp or projectDefinition-build again - otherwise, your changes are lost.
+#
+# Notice, that the name bc.mak is historical (from times, when only borland c was supported).
+# This file contains make rules for the win32 platform using either borland-bcc or visual-c.
+# It shares common definitions with the unix-make in Make.spec.
+# The bc.mak supports the following targets:
+#    bmake         - compile all st-files to a classLib (dll)
+#    bmake clean   - clean all temp files
+#    bmake clobber - clean all
+#
+# Historic Note:
+#  this used to contain only rules to make with borland
+#    (called via bmake, by "make.exe -f bc.mak")
+#  this has changed; it is now also possible to build using microsoft visual c
+#    (called via vcmake, by "make.exe -f bc.mak -DUSEVC")
+#
+TOP=..\..
+INCLUDE_TOP=$(TOP)\..
+
+
+
+!INCLUDE $(TOP)\rules\stdHeader_bc
+
+!INCLUDE Make.spec
+
+LIBNAME=libstx_goodies_smallsense
+MODULE_PATH=goodies\smallsense
+RESFILES=smallsense.$(RES)
+
+
+
+LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser -I$(INCLUDE_TOP)\stx\goodies\regex -I$(INCLUDE_TOP)\stx\goodies\sunit -I$(INCLUDE_TOP)\stx\libbasic -I$(INCLUDE_TOP)\stx\libbasic2 -I$(INCLUDE_TOP)\stx\libbasic3 -I$(INCLUDE_TOP)\stx\libcomp -I$(INCLUDE_TOP)\stx\libhtml -I$(INCLUDE_TOP)\stx\libjava -I$(INCLUDE_TOP)\stx\libjava\tools -I$(INCLUDE_TOP)\stx\libtool -I$(INCLUDE_TOP)\stx\libview -I$(INCLUDE_TOP)\stx\libview2 -I$(INCLUDE_TOP)\stx\libwidg -I$(INCLUDE_TOP)\stx\libwidg2
+LOCALDEFINES=
+
+STCLOCALOPT=-package=$(PACKAGE) -I. $(LOCALINCLUDES) -headerDir=. $(STCLOCALOPTIMIZATIONS) $(STCWARNINGS) $(LOCALDEFINES)  -varPrefix=$(LIBNAME)
+LOCALLIBS=
+
+OBJS= $(COMMON_OBJS) $(WIN32_OBJS)
+
+ALL::  classLibRule
+
+classLibRule: $(OUTDIR) $(OUTDIR)$(LIBNAME).dll
+
+!INCLUDE $(TOP)\rules\stdRules_bc
+
+# build all mandatory prerequisite packages (containing superclasses) for this package
+prereq:
+	pushd ..\..\libbasic & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\refactoryBrowser\helpers & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\refactoryBrowser\parser & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\regex & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libbasic2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libbasic3 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libcomp & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libui & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libview & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libview2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\refactoryBrowser\browser & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\sunit & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libwidg & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\refactoryBrowser\lint & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libhtml & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libwidg2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\libtool & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+
+
+
+
+
+
+
+test: $(TOP)\goodies\builder\reports\NUL
+	pushd $(TOP)\goodies\builder\reports & $(MAKE_BAT)
+	$(TOP)\goodies\builder\reports\report-runner.bat -D . -r Builder::TestReport -p $(PACKAGE)
+        
+clean::
+	del *.$(CSUFFIX)
+
+
+# BEGINMAKEDEPEND --- do not remove this line; make depend needs it
+$(OUTDIR)SmallSense__AbstractDIalog.$(O) SmallSense__AbstractDIalog.$(H): SmallSense__AbstractDIalog.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractSearchProcessor.$(O) SmallSense__AbstractSearchProcessor.$(H): SmallSense__AbstractSearchProcessor.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CodeHighlightingService.$(O) SmallSense__CodeHighlightingService.$(H): SmallSense__CodeHighlightingService.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__BackgroundSourceProcessingService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeHighlightingService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CodeNavigationService.$(O) SmallSense__CodeNavigationService.$(H): SmallSense__CodeNavigationService.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeNavigationService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionContext.$(O) SmallSense__CompletionContext.$(H): SmallSense__CompletionContext.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionController.$(O) SmallSense__CompletionController.$(H): SmallSense__CompletionController.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg\EditTextViewCompletionSupport.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionEngine.$(O) SmallSense__CompletionEngine.$(H): SmallSense__CompletionEngine.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionResult.$(O) SmallSense__CompletionResult.$(H): SmallSense__CompletionResult.st $(INCLUDE_TOP)\stx\libbasic\Collection.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\OrderedCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\SequenceableCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\SortedCollection.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompletionView.$(O) SmallSense__CompletionView.$(H): SmallSense__CompletionView.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview\DisplaySurface.$(H) $(INCLUDE_TOP)\stx\libview\GraphicsMedium.$(H) $(INCLUDE_TOP)\stx\libview\SimpleView.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CriticsWindow.$(O) SmallSense__CriticsWindow.$(H): SmallSense__CriticsWindow.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__EditService.$(O) SmallSense__EditService.$(H): SmallSense__EditService.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__EditSupport.$(O) SmallSense__EditSupport.$(H): SmallSense__EditSupport.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Info.$(O) SmallSense__Info.$(H): SmallSense__Info.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Manager.$(O) SmallSense__Manager.$(H): SmallSense__Manager.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__NavigatorStep.$(O) SmallSense__NavigatorStep.$(H): SmallSense__NavigatorStep.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PO.$(O) SmallSense__PO.$(H): SmallSense__PO.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeIndex.$(O) SmallSense__ParseTreeIndex.$(H): SmallSense__ParseTreeIndex.st $(INCLUDE_TOP)\stx\libbasic\Collection.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\OrderedCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\SequenceableCollection.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeIndexEntry.$(O) SmallSense__ParseTreeIndexEntry.$(H): SmallSense__ParseTreeIndexEntry.st $(INCLUDE_TOP)\stx\libbasic\Magnitude.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ParseTreeInspector.$(O) SmallSense__ParseTreeInspector.$(H): SmallSense__ParseTreeInspector.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\HierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SelectorNode.$(O) SmallSense__SelectorNode.$(H): SmallSense__SelectorNode.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libcomp\ParseNode.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SettingsAppl.$(O) SmallSense__SettingsAppl.$(H): SmallSense__SettingsAppl.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\AbstractSettingsApplication.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkChecker.$(O) SmallSense__SmalltalkChecker.$(H): SmallSense__SmalltalkChecker.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint\SmalllintChecker.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkInferencerParameters.$(O) SmallSense__SmalltalkInferencerParameters.$(H): SmallSense__SmalltalkInferencerParameters.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkLintService.$(O) SmallSense__SmalltalkLintService.$(H): SmallSense__SmalltalkLintService.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__BackgroundSourceProcessingService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeViewService.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkParseNodeVisitor.$(O) SmallSense__SmalltalkParseNodeVisitor.$(H): SmallSense__SmalltalkParseNodeVisitor.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkParser.$(O) SmallSense__SmalltalkParser.$(H): SmallSense__SmalltalkParser.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libcomp\AbstractSyntaxHighlighter.$(H) $(INCLUDE_TOP)\stx\libcomp\Parser.$(H) $(INCLUDE_TOP)\stx\libcomp\Scanner.$(H) $(INCLUDE_TOP)\stx\libcomp\SyntaxHighlighter.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkQuickFixer.$(O) SmallSense__SmalltalkQuickFixer.$(H): SmallSense__SmalltalkQuickFixer.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkSyntaxHighlighter.$(O) SmallSense__SmalltalkSyntaxHighlighter.$(H): SmallSense__SmalltalkSyntaxHighlighter.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libcomp\AbstractSyntaxHighlighter.$(H) $(INCLUDE_TOP)\stx\libcomp\Parser.$(H) $(INCLUDE_TOP)\stx\libcomp\Scanner.$(H) $(INCLUDE_TOP)\stx\libcomp\SyntaxHighlighter.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkUnacceptedMethodEnvironment.$(O) SmallSense__SmalltalkUnacceptedMethodEnvironment.$(H): SmallSense__SmalltalkUnacceptedMethodEnvironment.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\BrowserEnvironment.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternMatcher.$(O) SmallSense__TokenPatternMatcher.$(H): SmallSense__TokenPatternMatcher.st $(INCLUDE_TOP)\stx\goodies\regex\RxMatcher.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternParser.$(O) SmallSense__TokenPatternParser.$(H): SmallSense__TokenPatternParser.st $(INCLUDE_TOP)\stx\goodies\regex\RxCharSetParser.$(H) $(INCLUDE_TOP)\stx\goodies\regex\RxParser.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternToken.$(O) SmallSense__TokenPatternToken.$(H): SmallSense__TokenPatternToken.st $(INCLUDE_TOP)\stx\goodies\regex\RxsNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenPatternTokenSet.$(O) SmallSense__TokenPatternTokenSet.$(H): SmallSense__TokenPatternTokenSet.st $(INCLUDE_TOP)\stx\goodies\regex\RxsCharSet.$(H) $(INCLUDE_TOP)\stx\goodies\regex\RxsNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TokenStream.$(O) SmallSense__TokenStream.$(H): SmallSense__TokenStream.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Type.$(O) SmallSense__Type.$(H): SmallSense__Type.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__TypeHolder.$(O) SmallSense__TypeHolder.$(H): SmallSense__TypeHolder.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)stx_goodies_smallsense.$(O) stx_goodies_smallsense.$(H): stx_goodies_smallsense.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractJavaCompletionEngine.$(O) SmallSense__AbstractJavaCompletionEngine.$(H): SmallSense__AbstractJavaCompletionEngine.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractListDialog.$(O) SmallSense__AbstractListDialog.$(H): SmallSense__AbstractListDialog.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassInfo.$(O) SmallSense__ClassInfo.$(H): SmallSense__ClassInfo.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__Info.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassPO.$(O) SmallSense__ClassPO.$(H): SmallSense__ClassPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassSearchProcessor.$(O) SmallSense__ClassSearchProcessor.$(H): SmallSense__ClassSearchProcessor.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassType.$(O) SmallSense__ClassType.$(H): SmallSense__ClassType.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__Type.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CompositeProcessor.$(O) SmallSense__CompositeProcessor.$(H): SmallSense__CompositeProcessor.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ConstantPO.$(O) SmallSense__ConstantPO.$(H): SmallSense__ConstantPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__GenericEditSupport.$(O) SmallSense__GenericEditSupport.$(H): SmallSense__GenericEditSupport.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__EditSupport.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ImplementorSearchProcessor.$(O) SmallSense__ImplementorSearchProcessor.$(H): SmallSense__ImplementorSearchProcessor.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaEditSupport.$(O) SmallSense__JavaEditSupport.$(H): SmallSense__JavaEditSupport.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__EditSupport.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaImportPO.$(O) SmallSense__JavaImportPO.$(H): SmallSense__JavaImportPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodBindingPO.$(O) SmallSense__MethodBindingPO.$(H): SmallSense__MethodBindingPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodInfo.$(O) SmallSense__MethodInfo.$(H): SmallSense__MethodInfo.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__Info.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodPO.$(O) SmallSense__MethodPO.$(H): SmallSense__MethodPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PackagePO.$(O) SmallSense__PackagePO.$(H): SmallSense__PackagePO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PluggablePO.$(O) SmallSense__PluggablePO.$(H): SmallSense__PluggablePO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PluggableSearchProcessor.$(O) SmallSense__PluggableSearchProcessor.$(H): SmallSense__PluggableSearchProcessor.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSearchProcessor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkCompletionEngine.$(O) SmallSense__SmalltalkCompletionEngine.$(H): SmallSense__SmalltalkCompletionEngine.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkEditSupport.$(O) SmallSense__SmalltalkEditSupport.$(H): SmallSense__SmalltalkEditSupport.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__EditSupport.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkInferencer.$(O) SmallSense__SmalltalkInferencer.$(H): SmallSense__SmalltalkInferencer.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__SmalltalkParseNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SmalltalkParseNodeFinder.$(O) SmallSense__SmalltalkParseNodeFinder.$(H): SmallSense__SmalltalkParseNodeFinder.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__SmalltalkParseNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__SnippetPO.$(O) SmallSense__SnippetPO.$(H): SmallSense__SnippetPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__UnionType.$(O) SmallSense__UnionType.$(H): SmallSense__UnionType.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__SmalltalkInferencerParameters.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__Type.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__UnknownType.$(O) SmallSense__UnknownType.$(H): SmallSense__UnknownType.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__Type.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__VariableBindingPO.$(O) SmallSense__VariableBindingPO.$(H): SmallSense__VariableBindingPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__VariablePO.$(O) SmallSense__VariablePO.$(H): SmallSense__VariablePO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractJavaCompletionEngineSimple.$(O) SmallSense__AbstractJavaCompletionEngineSimple.$(H): SmallSense__AbstractJavaCompletionEngineSimple.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractSearchDialog.$(O) SmallSense__AbstractSearchDialog.$(H): SmallSense__AbstractSearchDialog.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__AbstractSelectDialog.$(O) SmallSense__AbstractSelectDialog.$(H): SmallSense__AbstractSelectDialog.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__GroovyEditSupport.$(O) SmallSense__GroovyEditSupport.$(H): SmallSense__GroovyEditSupport.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__EditSupport.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__JavaEditSupport.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaCompletionEngine.$(O) SmallSense__JavaCompletionEngine.$(H): SmallSense__JavaCompletionEngine.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaConstructorPO.$(O) SmallSense__JavaConstructorPO.$(H): SmallSense__JavaConstructorPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__MethodPO.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodKeywordRestPO.$(O) SmallSense__MethodKeywordRestPO.$(H): SmallSense__MethodKeywordRestPO.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__MethodPO.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__PO.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libwidg2\AbstractHierarchicalItem.$(H) $(INCLUDE_TOP)\stx\libwidg2\CompactHierarchicalItem.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ClassSearchDialog.$(O) SmallSense__ClassSearchDialog.$(H): SmallSense__ClassSearchDialog.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSearchDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__JavaCompletionEngineSimple.$(O) SmallSense__JavaCompletionEngineSimple.$(H): SmallSense__JavaCompletionEngineSimple.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractJavaCompletionEngineSimple.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__MethodSearchDialog.$(O) SmallSense__MethodSearchDialog.$(H): SmallSense__MethodSearchDialog.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSearchDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__Navigator.$(O) SmallSense__Navigator.$(H): SmallSense__Navigator.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSearchDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__PackageSelectDialog.$(O) SmallSense__PackageSelectDialog.$(H): SmallSense__PackageSelectDialog.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSelectDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__ProtocolSelectDialog.$(O) SmallSense__ProtocolSelectDialog.$(H): SmallSense__ProtocolSelectDialog.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractDIalog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractListDialog.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractSelectDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\SimpleDialog.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__GroovyCompletionEngineSimple.$(O) SmallSense__GroovyCompletionEngineSimple.$(H): SmallSense__GroovyCompletionEngineSimple.st $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractJavaCompletionEngine.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__AbstractJavaCompletionEngineSimple.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__CompletionEngine.$(H) $(INCLUDE_TOP)\stx\goodies\smallsense\SmallSense__JavaCompletionEngineSimple.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint\RBBasicLintRule.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint\RBBlockLintRule.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint\RBContainsSmalltalkXEOLCommentRule.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint\RBLintRule.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\lint\RBTransformationRule.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBBlockNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBMethodNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBProgramNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBStatementNode.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBValueNode.$(H) $(INCLUDE_TOP)\stx\libbasic\Collection.$(H) $(INCLUDE_TOP)\stx\libbasic\CompiledCode.$(H) $(INCLUDE_TOP)\stx\libbasic\ConfigurableFeatures.$(H) $(INCLUDE_TOP)\stx\libbasic\Dictionary.$(H) $(INCLUDE_TOP)\stx\libbasic\ExecutableFunction.$(H) $(INCLUDE_TOP)\stx\libbasic\IdentityDictionary.$(H) $(INCLUDE_TOP)\stx\libbasic\Method.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\Set.$(H) $(INCLUDE_TOP)\stx\libbasic\UserPreferences.$(H) $(INCLUDE_TOP)\stx\libcomp\AssignmentNode.$(H) $(INCLUDE_TOP)\stx\libcomp\BlockNode.$(H) $(INCLUDE_TOP)\stx\libcomp\MessageNode.$(H) $(INCLUDE_TOP)\stx\libcomp\ParseErrorNode.$(H) $(INCLUDE_TOP)\stx\libcomp\ParseNode.$(H) $(INCLUDE_TOP)\stx\libcomp\Parser.$(H) $(INCLUDE_TOP)\stx\libcomp\PrimaryNode.$(H) $(INCLUDE_TOP)\stx\libcomp\PrimitiveNode.$(H) $(INCLUDE_TOP)\stx\libcomp\ReturnNode.$(H) $(INCLUDE_TOP)\stx\libcomp\Scanner.$(H) $(INCLUDE_TOP)\stx\libcomp\StatementNode.$(H) $(INCLUDE_TOP)\stx\libcomp\VariableNode.$(H) $(INCLUDE_TOP)\stx\libhtml\HTMLDocumentFrame.$(H) $(INCLUDE_TOP)\stx\libhtml\HTMLDocumentView.$(H) $(INCLUDE_TOP)\stx\libtool\DebugView.$(H) $(INCLUDE_TOP)\stx\libtool\InspectorView.$(H) $(INCLUDE_TOP)\stx\libtool\MultiViewToolApplication.$(H) $(INCLUDE_TOP)\stx\libtool\SystemBrowser.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__BackgroundSourceProcessingService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeCompletionService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeHighlightingService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeNavigationService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__CodeViewService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__Inspector2.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__LintService.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__NavigationState.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__NewSystemBrowser.$(H) $(INCLUDE_TOP)\stx\libtool\WorkspaceApplication.$(H) $(INCLUDE_TOP)\stx\libview\DisplaySurface.$(H) $(INCLUDE_TOP)\stx\libview\GraphicsMedium.$(H) $(INCLUDE_TOP)\stx\libview\ModalBox.$(H) $(INCLUDE_TOP)\stx\libview\SimpleView.$(H) $(INCLUDE_TOP)\stx\libview\StandardSystemView.$(H) $(INCLUDE_TOP)\stx\libview\TopView.$(H) $(INCLUDE_TOP)\stx\libview\View.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(H) $(INCLUDE_TOP)\stx\libview2\ToolApplicationModel.$(H) $(INCLUDE_TOP)\stx\libwidg\DialogBox.$(H) $(INCLUDE_TOP)\stx\libwidg\EditTextView.$(H) $(INCLUDE_TOP)\stx\libwidg\EditTextViewCompletionSupport.$(H) $(INCLUDE_TOP)\stx\libwidg\ListView.$(H) $(INCLUDE_TOP)\stx\libwidg\TextView.$(H) $(STCHDR)
+
+# ENDMAKEDEPEND --- do not remove this line
+
+# **Must be at end**
+
+# Enforce recompilation of package definition class if Mercurial working
+# copy state changes. Together with --guessVersion it ensures that package
+# definition class always contains correct binary revision string.
+!IFDEF HGROOT
+$(OUTDIR)stx_goodies_smallsense.$(O): $(HGROOT)\.hg\dirstate
+!ENDIF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bmake.bat	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,12 @@
+@REM -------
+@REM make using Borland bcc32
+@REM type bmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+make.exe -N -f bc.mak  %DEFINES% %*
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,1198 @@
+"{ Package: 'stx:goodies/smallsense' }"!
+
+!AssignmentNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+
+    aBlock value: #variable   value: variable.
+    aBlock value: #expression value: expression.
+
+    "Modified: / 26-11-2011 / 10:39:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AssignmentNode methodsFor:'accessing-SmallSense'!
+
+inferedType
+    expression isNil ifTrue:[ 
+        ^ SmallSense::Type unknown
+    ].
+    ^ expression inferedType
+
+    "Created: / 26-11-2011 / 12:38:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-04-2015 / 17:16:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!AssignmentNode methodsFor:'accessing-SmallSense'!
+
+inferedType: aSmallSenseType
+
+    ^ self shouldNotImplement
+
+    "Created: / 26-11-2011 / 12:37:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!BlockNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+    "Enumerates all direct children and evaluates a block
+     with its name (usually instVar name) and the node itself"
+
+    aBlock value:'statements' value: statements
+
+    "Created: / 20-09-2013 / 01:03:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ConfigurableFeatures class methodsFor:'queries-features'!
+
+hasSmallSenseEnabled
+
+    ^UserPreferences current smallSenseEnabled
+
+
+    "
+     ConfigurableFeatures hasSmallSenseEnabled
+     ConfigurableFeatures includesFeature:'SmallSenseEnabled'
+    "
+
+    "Created: / 27-11-2011 / 17:22:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!DebugView methodsFor:'event handling'!
+
+processShortcut:aKeyPressEvent
+    "a shortcut key event as forwarded from the keyboardProcessor - if there is the
+     shortcut key defined, process the shortcut and return true - otherwise false."
+
+    UserPreferences current smallSenseEnabled ifTrue:[   
+        (aKeyPressEvent key == #OpenNavigator or:[aKeyPressEvent rawKey == #CtrlT and:[(aKeyPressEvent targetView keyboardMap hasBindingFor: #OpenNavigator) not]]) ifTrue:[ 
+            SmallSense::Navigator open.                                                                      
+            ^ true
+        ].    
+    ].
+    ^ super processShortcut:aKeyPressEvent
+
+    "Created: / 25-01-2015 / 12:18:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 21:34:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!DialogBox class methodsFor:'smalltalk dialogs-SmallSense'!
+
+stx_goodies_smallsense_requestProject:title from:listOfProjects initialAnswer:initialTextOrNil suggestions:suggestions
+    "Ask for a project (package-id)"
+
+    <swizzle: #requestProject:from:initialAnswer:suggestions:>
+    "
+    stx_goodies_smallsense swizzle: (DialogBox class >> #stx_goodies_smallsense_requestProject:from:initialAnswer:suggestions:)
+    "
+
+    | dialog |
+
+    UserPreferences current smallSenseNewDialogsEnabled ifFalse:[ 
+        ^ self stx_libwidg_requestProject:title from:listOfProjects initialAnswer:initialTextOrNil suggestions:suggestions
+    ].
+    dialog := SmallSense::PackageSelectDialog new.
+    dialog title: title.
+    dialog filter: [ :pkg | listOfProjects includes: pkg ].
+    (initialTextOrNil notNil and:[initialTextOrNil ~~ PackageId noProjectID]) ifTrue:[
+        initialTextOrNil isEmpty ifTrue:[
+            suggestions size == 1 ifTrue:[
+                dialog pattern:   suggestions anElement. 
+                dialog selection: suggestions anElement. 
+            ].
+        ] ifFalse:[ 
+            dialog pattern: initialTextOrNil.
+            dialog selection: initialTextOrNil.
+        ]
+    ].
+    ^ dialog open.
+
+    "Created: / 25-11-2014 / 13:20:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 21-02-2015 / 08:59:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 21-02-2015 / 17:53:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!EditTextView methodsFor:'accessing-behavior'!
+
+autoIndent
+    ^ autoIndent
+! !
+
+!EditTextViewCompletionSupport methodsFor:'queries'!
+
+isCompletionViewShown
+    ^ completionView notNil and:[ completionView isVisible ]
+
+    "Created: / 13-08-2014 / 16:00:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!HTMLDocumentView methodsFor:'actions'!
+
+doQuickFix: quickFixNo
+    | app |
+
+    app := self application.
+    app notNil ifTrue:[
+	app doQuickFix: quickFixNo
+    ].
+
+    "Created: / 16-02-2012 / 14:18:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!InspectorView methodsFor:'initialization & release'!
+
+preRealize
+    "/ This method is an ugly hack to hook-in a a SmallSense completer.
+    "/ Things fall apart if somebody later defined preRealize on
+    "/ InspectorView...
+    UserPreferences current smallSenseCompletionEnabled ifTrue:[ 
+        | completion support |
+
+        support := SmallSense::EditSupport forLanguage: object class programmingLanguage.
+        support initializeForTextView: workspace.  
+        completion := SmallSense::CompletionController for: workspace. 
+        completion support: support.
+        workspace completionSupport: completion.  
+    ].
+    super preRealize
+
+    "Modified: / 12-02-2015 / 00:20:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MessageNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+
+    aBlock value: #receiver value: receiver.
+    argArray notNil ifTrue:[
+	argArray withIndexDo:[:node :idx|
+	    aBlock value: 'arg[' , idx printString , ']' value: node
+	]
+    ]
+
+    "Modified: / 26-11-2011 / 12:10:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!MessageNode methodsFor:'navigation-SmallSense'!
+
+navigateToUsing: navigator
+    navigator navigateToMessageNode: self.
+
+    "Created: / 24-09-2013 / 10:04:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Method methodsFor:'inspecting'!
+
+inspector2TabRBParseTreeInspector
+    <inspector2Tab>
+
+    ^ (self newInspector2Tab)
+        label:'Parse Tree (RB)';
+        priority:35;
+        application:
+                [
+                    | src node |
+
+                    src := self source.
+                    node := RBParser parseMethod: src.
+                    SmallSense::ParseTreeInspector new node:node source:src.
+                ];
+        yourself
+
+    "Created: / 15-10-2014 / 02:37:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Method methodsFor:'inspecting'!
+
+inspector2TabSTXParseTreeInspector
+    <inspector2Tab>
+
+    ^ (self newInspector2Tab)
+        label:'Parse Tree (ST/X)';
+        priority:36;
+        application:
+                [
+                    | src parser |
+
+                    src := self source.
+                    parser := self parserClass parseMethod: src.
+                    SmallSense::ParseTreeInspector new node:parser tree source:src.
+                ];
+        yourself
+
+    "Created: / 15-10-2014 / 11:23:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseErrorNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+    "superclass ParseNode says that I am responsible to implement this method"
+
+    ^ children withIndexDo:[:child :index |
+        aBlock value:'child[' , index printString , ']' value: child
+    ]
+
+    "Modified: / 20-09-2013 / 01:00:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+    "Enumerates all direct children and evaluates a block
+     with its name (usually instVar name) and the node itself"
+
+    self class allInstVarNames withIndexDo:[:n :i|
+        | v |
+
+        v := self instVarAt: i.
+        (v isKindOf: ParseNode) ifTrue:[
+            aBlock value: n value: v
+        ] ifFalse:[
+            (v isSequenceable) ifTrue:[
+                v withIndexDo:[ :v2 :i2|
+                    (v2 isKindOf: ParseNode) ifTrue:[
+                        aBlock value: (n, '[' , i2 printString , ']') value: v2.
+                    ]
+                ]
+            ]
+        ]
+    ]
+
+    "Created: / 26-11-2011 / 10:38:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 19-09-2013 / 18:18:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseNode methodsFor:'accessing-SmallSense'!
+
+inferedType
+
+    | t |
+    t := self objectAttributeAt:#inferedType.
+    t isNil ifTrue:[t := SmallSense::Type unknown].
+    ^t
+
+    "Created: / 26-11-2011 / 12:38:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 24-08-2013 / 20:46:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseNode methodsFor:'accessing-SmallSense'!
+
+inferedType: aSmallSenseType
+
+    ^ self objectAttributeAt:#inferedType put: aSmallSenseType
+
+    "Created: / 26-11-2011 / 12:37:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseNode methodsFor:'inspecting'!
+
+inspector2TabSTXParseTreeInspector
+    <inspector2Tab>
+
+    ^ (self newInspector2Tab)
+        label:'Parse Tree (ST/X)';
+        priority:36;
+        application:
+                [
+                    SmallSense::ParseTreeInspector new node:self source:nil.
+                ];
+        yourself
+
+    "Created: / 15-10-2014 / 11:23:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseNode methodsFor:'testing'!
+
+isSelector
+    "return true, if this is a node for an selctors"
+
+    ^ false
+
+    "Created: / 22-02-2011 / 21:44:45 / Jakub <zelenja7@fel.cvut.cz>"
+! !
+
+!ParseNode methodsFor:'navigation-SmallSense'!
+
+navigateToUsing:navigator
+    "Nothing by default, to overwritten by subclasses"
+
+    "Modified: / 24-09-2013 / 10:05:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Parser methodsFor:'inspecting'!
+
+inspector2TabSTXParseTreeInspector
+    <inspector2Tab>
+
+    ^ (self newInspector2Tab)
+        label:'Parse Tree (ST/X)';
+        priority:36;
+        application:
+                [
+                    | src parser |
+
+                    source isExternalStream ifFalse:[ 
+                        src := source collection 
+                    ].
+                    SmallSense::ParseTreeInspector new node:tree source:src.
+                ];
+        yourself
+
+    "Created: / 15-10-2014 / 11:23:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PrimaryNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+
+    "Initionally left blank, primary nodes have no children"
+
+    "Modified: / 26-11-2011 / 11:49:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!PrimitiveNode methodsFor:'accessing-SmallSense'!
+
+inferedType
+
+    ^ SmallSense::Type withClass: UndefinedObject "/ Not really true, should be 'void'
+
+    "Created: / 08-12-2013 / 22:25:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBBlockNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+    arguments withIndexDo:[:statement :index |
+        aBlock value: 'argument[', index printString ,']' value: statement
+    ].
+    body statements withIndexDo:[:statement :index |
+        aBlock value: 'statement[', index printString ,']' value: statement
+    ]
+
+    "Created: / 15-10-2014 / 10:42:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBContainsSmalltalkXEOLCommentRule methodsFor:'accessing'!
+
+fixes: fixer
+    | changes |
+
+    changes := self changes.
+    changes notEmptyOrNil ifTrue:[
+        fixer fix
+            rule: self;
+            label:'Change EOL comments to standard Smalltalk comments';
+            action: [ fixer apply:
+                ((ChangeSet withAll:changes) name: self name)
+            ].
+    ]
+
+    "Created: / 01-02-2012 / 12:11:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 16:46:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBLintRule methodsFor:'accessing'!
+
+fixes: aSmallSenseQuickFixer
+    "Adds all possible code fixes to given quick fixer.
+     Default is to do nothing, meaning that there are
+     no quickfixes available"
+
+    "Created: / 01-02-2012 / 12:09:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBMethodNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+    arguments withIndexDo:[:statement :index |
+        aBlock value: 'argument[', index printString ,']' value: statement
+    ].
+    body statements withIndexDo:[:statement :index |
+        aBlock value: 'statement[', index printString ,']' value: statement
+    ]
+
+    "Created: / 15-10-2014 / 09:28:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-10-2014 / 10:41:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBProgramNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+
+    "Enumerates all direct children and evaluates a block
+     with its name (usually instVar name) and the node itself"
+
+    self class allInstVarNames withIndexDo:[:n :i|
+        | v |
+
+        n ~~ #parent ifTrue:[
+            v := self instVarAt: i.
+            (v isKindOf: RBProgramNode) ifTrue:[
+                aBlock value: n value: v
+            ] ifFalse:[
+                (v isSequenceable) ifTrue:[
+                    v withIndexDo:[ :v2 :i2|
+                        (v2 isKindOf: RBProgramNode) ifTrue:[
+                            aBlock value: (n, '[' , i2 printString , ']') value: v2.
+                        ]
+                    ]
+                ]
+            ]
+        ]
+    ]
+
+    "Created: / 15-10-2014 / 10:39:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBProgramNode methodsFor:'accessing'!
+
+endPosition
+    ^ self stop
+
+    "Created: / 15-10-2014 / 09:34:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBProgramNode methodsFor:'accessing'!
+
+startPosition
+    ^ self start
+
+    "Created: / 15-10-2014 / 09:34:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBTransformationRule methodsFor:'accessing'!
+
+fixes: fixer
+    | changes |
+
+    changes := self changes.
+    changes notEmptyOrNil ifTrue:[
+        fixer fix
+            rule: self;    
+            label:'Rewrite the code';
+            action: [ fixer apply:
+                ((ChangeSet withAll:self changes) name: self name)
+            ].
+    ]
+
+    "Created: / 01-02-2012 / 12:11:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-12-2014 / 16:46:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ReturnNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+    aBlock value: 'expression' value: expression.
+
+    "Created: / 10-04-2014 / 08:15:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!StatementNode methodsFor:'enumeration'!
+
+childNamesAndValuesDo:aBlock
+    | stmt index |
+    stmt := self.
+    index := 1.
+    [ stmt notNil ] whileTrue:[
+        | expr |
+
+        stmt isReturnNode ifTrue:[
+            expr := stmt.
+        ] ifFalse:[
+            expr := stmt expression.
+        ].
+        aBlock value: ('statement[%1]' bindWith: index) value: expr.
+        stmt := stmt nextStatement.
+        index := index + 1.
+    ]
+
+    "Modified: / 10-04-2014 / 08:13:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!StatementNode methodsFor:'accessing-SmallSense'!
+
+inferedType
+
+    ^ expression inferedType
+
+    "Created: / 26-11-2011 / 12:38:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!StatementNode methodsFor:'accessing-SmallSense'!
+
+inferedType: aSmallSenseType
+
+    ^ self shouldNotImplement
+
+    "Created: / 26-11-2011 / 12:37:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::CodeCompletionService class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ (SmallSense::EditService ? self) basicNew initialize.
+
+    "Created: / 27-07-2013 / 22:47:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-11-2014 / 15:40:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::CodeHighlightingService class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ (SmallSense::CodeHighlightingService ? self) basicNew initialize.
+
+    "Created: / 27-07-2013 / 22:47:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2013 / 14:32:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::CodeNavigationService class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ (SmallSense::CodeNavigationService ? self) basicNew initialize.
+
+    "Created: / 27-07-2013 / 22:47:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-09-2013 / 14:32:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::Inspector2 methodsFor:'event handling'!
+
+processShortcut:aKeyPressEvent
+    "a shortcut key event as forwarded from the keyboardProcessor - if there is the
+     shortcut key defined, process the shortcut and return true - otherwise false."
+
+    UserPreferences current smallSenseEnabled ifTrue:[   
+        (aKeyPressEvent key == #OpenNavigator or:[aKeyPressEvent rawKey == #CtrlT and:[(aKeyPressEvent targetView keyboardMap hasBindingFor: #OpenNavigator) not]]) ifTrue:[ 
+            SmallSense::Navigator open.
+            ^ true
+        ].    
+    ].
+    ^ super processShortcut:aKeyPressEvent
+
+    "Created: / 25-01-2015 / 12:18:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 21:34:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::LintService methodsFor:'event handling'!
+
+buttonPress:button x:x y:y in:view 
+    |lineNr|
+
+    view == gutterView ifTrue:[
+        button == 1 ifTrue:[
+            lineNr := textView yVisibleToLineNr:y.
+            lineNr notNil ifTrue:[ 
+                ^ self showInfoWindowForLine: lineNr 
+            ].
+            ^ false.
+        ].
+    ].
+    ^ false
+
+    "Created: / 30-01-2012 / 21:04:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-12-2014 / 10:01:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::LintService methodsFor:'private'!
+
+showInfoWindowForLine: lineNo
+    | ann |
+
+    ann := self annotationAtLine: lineNo.
+    ann isNil ifTrue:[ ^ false ].
+
+    SmallSense::CriticsWindow new
+        rule: ann rule;
+        codeView: codeView;
+        allButOpen;
+        openWindowAt: (Screen current pointerPosition - (20@20)).
+
+    ^true
+
+    "Created: / 30-01-2012 / 21:04:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 03-12-2014 / 10:00:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NavigationState methodsFor:'aspects - SmallSense'!
+
+stx_goodies_smallsense_selectedClasses
+    <swizzle: #selectedClasses>
+    selectedClasses isNil ifTrue:[
+        selectedClasses := nil asValue.
+        (ConfigurableFeatures includesFeature:'SmallSenseEnabled') ifTrue:[
+            selectedClasses
+                onChangeEvaluate:[
+                    selectedClasses value ? #() do:[:cls |
+                        (Smalltalk at:#'SmallSense::Manager') instance updateInfoForClass:cls.
+                    ].
+                ]
+        ]
+    ].
+    ^ selectedClasses
+
+    "Created: / 24-08-2013 / 21:53:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'user actions-events'!
+
+processShortcut: aKeyPressEvent
+    UserPreferences current smallSenseEnabled ifTrue:[
+        aKeyPressEvent isKeyPressEvent ifTrue:[
+            (aKeyPressEvent key == #OpenNavigator or:[aKeyPressEvent rawKey == #CtrlT and:[(aKeyPressEvent targetView keyboardMap hasBindingFor: #OpenNavigator) not]]) ifTrue:[ 
+                self searchMenuOpenNavigatorOnDeclarations.
+                ^ true
+            ].
+        ].
+    ].
+    ^ super processShortcut: aKeyPressEvent
+
+    "Created: / 01-02-2015 / 07:22:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 21:34:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'private-searching-smallsense'!
+
+searchCompletionBlock_SmallSense
+    "This returns a class/selector name completion block that uses
+     standard DoWhatIMeanSupport"
+
+    ^ [:patternString | self smallSenseSearchCompletion:patternString ]
+
+    "Created: / 25-11-2013 / 12:27:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menu actions-searching-SmallSense'!
+
+searchMenuOpenNavigatorOnDeclarations
+    "Open a SmallSense navigator on definitions (i.e.,
+     navugating to a class or or method implementor)"
+
+    | result |    
+
+    result := SmallSense::Navigator new open.
+    result isBehavior ifTrue:[
+        self createBuffer.
+        self switchToClass: result.
+        ^ self
+    ].
+    result isMethod ifTrue:[ 
+        self createBuffer.
+        self switchToClass: result mclass selector: result selector.
+        ^ self
+    ].
+    result isCollection ifTrue:[ 
+        (result allSatisfy:[:e|e isMethod]) ifTrue:[ 
+            self  spawnMethodBrowserForSearch:[ result ] 
+                  sortBy:#class 
+                  in:#newBuffer 
+                  label:(resources string: 'Implementors of %1' with: result anElement selector storeString)
+        ].
+        ^ self
+    ].
+    ^ self
+
+    "Created: / 23-01-2015 / 20:31:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 08-02-2015 / 08:21:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'private-searching-smallsense'!
+
+smallSenseSearchCompletion:patternString
+    "/sorry, no method search yet"
+
+    ^ self smallSenseSearchCompletionNewForClass:patternString
+
+    "Modified: / 04-08-2011 / 19:05:28 / cg"
+    "Created: / 04-12-2011 / 22:22:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'private-searching-smallsense'!
+
+smallSenseSearchCompletionBlock
+    "This returns a class/selector name completion block that uses
+     standard DoWhatIMeanSupport"
+
+    ^ [:patternString | self smallSenseSearchCompletion:patternString ]
+
+    "Modified: / 04-08-2011 / 19:05:28 / cg"
+    "Created: / 04-12-2011 / 22:13:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'private-searching-smallsense'!
+
+smallSenseSearchCompletionEntryForClass:aClass showPrefix:showPrefix
+    ^ (SmallSense::ClassPO new)
+        klass:aClass;
+        showPrefix:showPrefix.
+
+    "Created: / 06-04-2012 / 12:55:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2013 / 12:16:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'private-searching-smallsense'!
+
+smallSenseSearchCompletionNewForClass:patternString
+    | env  pattern  matcher  matches  relax  withPrefix |
+
+    patternString isEmptyOrNil ifTrue:[
+        ^ #( '' #() )
+    ].
+    env := self theSingleSelectedNamespace ? #Smalltalk.
+    env = NavigatorModel nameListEntryForALL ifTrue:[
+        env := #Smalltalk
+    ].
+    env := Smalltalk at:env.
+    withPrefix := patternString includes:$:.
+    pattern := StringPattern readFrom:patternString onError:[ ^ #( '' #() ) ].
+    withPrefix ifTrue:[
+        matcher := [:cls | pattern match:cls name ]
+    ] ifFalse:[
+        matcher := [:cls | pattern match:cls nameWithoutPrefix ]
+    ].
+    relax := 1.
+    [
+        matches isEmptyOrNil and:[ relax <= 3 ]
+    ] whileTrue:[
+        matches := OrderedCollection new.
+        env
+            keysDo:[:nm |
+                | cls |
+
+                cls := env at:nm.
+                (cls notNil and:[ cls isBehavior and:[ (matches includesIdentical:cls) not ] ])
+                        ifTrue:[
+                            "cls isJavaClass"false ifTrue:[
+                                cls isAnonymous ifFalse:[
+                                    (matcher value:cls) ifTrue:[
+                                        matches add:cls
+                                    ].
+                                ].
+                            ] ifFalse:[
+                                (matcher value:cls) ifTrue:[
+                                    matches add:cls
+                                ].
+                            ]
+                        ].
+            ].
+        relax := relax + 1.
+    ].
+    matches isEmpty ifTrue:[
+        ^ #( nil #() )
+    ] ifFalse:[
+        matches := matches
+                collect:[:cls |
+                    self smallSenseSearchCompletionEntryForClass:cls showPrefix:withPrefix
+                ].
+        ^ {
+            matches first.
+            matches
+        }
+    ]
+
+    "Created: / 06-04-2012 / 12:56:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-08-2014 / 13:10:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'private-dialogs-SmallSense'!
+
+stx_goodies_smallsense_askForMethodCategory:question title:boxTitle okLabel:okLabel list:someCategories recentList:recentListOrNil initialAnswer:initialText
+    "convenient helper method: setup a box asking for a method category"
+
+    <swizzle: #askForMethodCategory:title:okLabel:list:recentList:initialAnswer:>
+
+    | dialog |
+
+    UserPreferences current smallSenseNewDialogsEnabled ifFalse:[ 
+        ^ self stx_libtool_askForMethodCategory:question title:boxTitle okLabel:okLabel list:someCategories recentList:recentListOrNil initialAnswer:initialText     
+    ].
+    dialog := SmallSense::ProtocolSelectDialog new.   
+    dialog title: (resources string: question).
+    dialog addButtonCancel.   
+    dialog addButtonAcceptWithLabel: (resources string: okLabel).  
+    initialText notNil ifTrue:[ 
+        dialog pattern: initialText.
+        dialog selection: initialText. 
+    ].
+    ^ dialog open
+    "
+    stx_goodies_smallsense swizzle: (Tools::NewSystemBrowser >> #stx_goodies_smallsense_askForMethodCategory:title:okLabel:list:recentList:initialAnswer:)
+    "
+
+    "Created: / 09-01-2015 / 10:44:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 21-02-2015 / 17:52:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser class methodsFor:'utilities'!
+
+stx_goodies_smallsense_askForClassToSearch:doWhatByDefault single:singleClass msgTail:msgTail resources:resourcesOrNil filter:filterOrNil forBrowser:aBrowserOrNil thenDo:aBlock
+    "utility common code for both opening a new browser on a class and
+     to search for a class in an existing browser.
+     If singleClass is true, a single class will be asked for and browsed,
+     otherwise, a match pattern is allowed and a multi-class browser is opened.
+     Moved from instance protocol for better reusability."
+
+    <swizzle: #askForClassToSearch:single:msgTail:resources:filter:forBrowser:thenDo:>
+
+    |classes box boxLabel title okText okText2 okText3 className canFind doWhat doWhat2 doWhat3 resources showFullNameHolder onlyShowJavaClassesHolder|
+
+    UserPreferences current smallSenseNewDialogsEnabled ifFalse:[ 
+        ^ self stx_libtool_askForClassToSearch:doWhatByDefault single:singleClass msgTail:msgTail resources:resourcesOrNil filter:filterOrNil forBrowser:aBrowserOrNil thenDo:aBlock
+    ].
+
+    resources := resourcesOrNil ? self classResources.
+    showFullNameHolder := (LastClassSearchBoxShowedFullName ? false) asValue.
+    onlyShowJavaClassesHolder := (LastClassSearchBoxShowedJavaOnly ? false) asValue.
+
+    doWhat := doWhatByDefault.
+    canFind := aBrowserOrNil notNil
+               and:[aBrowserOrNil navigationState notNil and:[ aBrowserOrNil navigationState isFullBrowser ]].
+
+    (doWhat isNil or:[aBrowserOrNil isNil]) ifTrue:[
+        title := 'Select a class'.
+        boxLabel := (resources string:'Select a class').
+        okText := 'OK'.
+        okText2 := nil. doWhat2 := nil.
+        okText3 := nil. doWhat3 := nil.
+    ] ifFalse:[
+        title := (singleClass ifTrue:[ 'Class to browse' ] ifFalse:[ 'Class(es) to browse' ]).
+        boxLabel := (resources string:'Browse or Search').
+
+        (doWhat isNil and:[canFind not]) ifTrue:[
+            doWhat := #newBuffer.
+        ].
+
+        doWhat == #newBrowser ifTrue:[
+            okText := 'Open New Window'.
+            okText2 := 'Open New Buffer'. doWhat2 := #newBuffer.
+            okText3 := 'Open'.       doWhat3 := nil.
+        ] ifFalse:[ doWhat == #newBuffer ifTrue:[
+            okText := 'Open New Buffer'.
+            okText2 := 'Open New Window'.   doWhat2 := #newBrowser.
+            okText3 := 'Open'.       doWhat3 := nil.
+        ] ifFalse:[
+            title := (singleClass ifTrue:[ 'Class to find' ] ifFalse:[ 'Class(es) to find' ]).
+            okText := 'Open'.
+            okText2 := 'Open New Window'.   doWhat2 := #newBrowser.
+            okText3 := 'Open New Buffer'. doWhat3 := #newBuffer.
+        ]].
+    ].
+
+    box := SmallSense::ClassSearchDialog new.
+    box multiselect: true.
+
+    "button3" "okButton" "button2" "cancel"
+
+    box addButtonCancel.
+    doWhat notNil ifTrue:[
+        box addButtonWithLabel: (resources string:okText) action: [ box doAccept ] enablement: box acceptEnabledHolder.
+        (aBrowserOrNil notNil and:[aBrowserOrNil navigationState isFullBrowser]) "singleClass" ifTrue:[
+            box addButtonWithLabel: (resources string:okText3) action: [ doWhat := doWhat3. box doAccept ] enablement: box acceptEnabledHolder.
+        ].
+        box addButtonWithLabel: (resources string:okText2) action: [ doWhat := doWhat2. box doAccept ] enablement: box acceptEnabledHolder.
+    ] ifFalse:[
+        box addButtonAccept.
+    ].
+
+
+
+    classes := box open.
+    classes isEmptyOrNil ifTrue:[ ^ nil ].
+    self assert: classes size == 1.
+    className := classes anElement name.
+
+
+    LastClassSearchBoxShowedFullName := showFullNameHolder value.
+    LastClassSearchBoxShowedJavaOnly := onlyShowJavaClassesHolder value.
+
+    (doWhat isNil or:[aBrowserOrNil isNil]) ifTrue:[
+        aBlock notNil ifTrue:[aBlock value:className optionalArgument:singleClass and:doWhat].
+        ^ className
+    ].
+
+    aBrowserOrNil withSearchCursorDo:[
+        aBlock value:className value:singleClass value:doWhat.
+    ].
+    ^ className
+
+    "Created: / 28-04-2014 / 23:41:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 13:08:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseBackgroundLintEnabled
+    "Return true if SmallSense background source checking is enabled"
+
+    ^self at:#smallSenseBackgroundLintEnabled ifAbsent:[false]
+
+    "Created: / 30-01-2012 / 19:59:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseBackgroundLintEnabled: aBoolean
+    "Return true if SmallSense background source checking is enabled"
+
+    ^self at:#smallSenseBackgroundLintEnabled put: aBoolean
+
+    "
+	UserPreferences current smallSenseBackgroundLintEnabled
+	UserPreferences current smallSenseBackgroundLintEnabled: true
+	UserPreferences current smallSenseBackgroundLintEnabled: false
+    "
+
+    "Created: / 30-01-2012 / 20:00:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseBackgroundTypingEnabled
+    "Return true if SmallSense background source checking is enabled"
+
+    ^self at:#smallSenseBackgroundTypingEnabled ifAbsent:[false]
+
+    "Created: / 04-02-2012 / 21:41:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseBackgroundTypingEnabled: aBoolean
+    "Return true if SmallSense background source checking is enabled"
+
+    ^self at:#smallSenseBackgroundTypingEnabled put: aBoolean
+
+    "
+	UserPreferences current smallSenseBackgroundTypingEnabled
+	UserPreferences current smallSenseBackgroundTypingEnabled: true
+	UserPreferences current smallSenseBackgroundTypingEnabled: false
+    "
+
+    "Created: / 04-02-2012 / 21:41:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseCompleteIfUnambiguous
+
+    ^self at:#smallSenseCompleteIfUnambiguous ifAbsent:[false]
+
+    "Created: / 18-01-2014 / 23:08:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseCompleteIfUnambiguous: aBoolean
+
+    ^self at:#smallSenseCompleteIfUnambiguous put: aBoolean.
+
+    "
+    UserPreferences current smallSenseCompleteIfUnambiguous
+    UserPreferences current smallSenseCompleteIfUnambiguous: true.
+    UserPreferences current smallSenseCompleteIfUnambiguous: false.
+    "
+
+    "Created: / 18-01-2014 / 23:08:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseCompletionEnabled
+
+    ^self at:#smallSenseCompletionEnabled ifAbsent:[self smallSenseEnabled]
+
+    "Created: / 27-02-2014 / 09:29:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseCompletionEnabled: aBoolean
+
+    ^self at:#smallSenseCompletionEnabled put: aBoolean
+
+    "Created: / 27-02-2014 / 09:29:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseElectricEditSupportEnabled
+    ^ self at:#smallSenseElectricEditSupportEnabled ifAbsent:[ false ].
+
+    "Created: / 02-05-2015 / 21:57:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseElectricEditSupportEnabled: aBoolean
+
+    ^self at:#smallSenseElectricEditSupportEnabled put: aBoolean
+
+    "Created: / 02-05-2015 / 21:57:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseEnabled
+    "Return true if SmallSense is enabled"
+
+    ^self at:#smallSenseEnabled ifAbsent:[false]
+
+    "Created: / 27-11-2011 / 17:20:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseEnabled: aBoolean
+    "enable/disable SmallSense"
+
+    ^self at:#smallSenseEnabled put: aBoolean.
+
+    "
+    UserPreferences current smallSenseEnabled.
+    UserPreferences current smallSenseEnabled: true.
+    UserPreferences current smallSenseEnabled: false.
+    "
+
+    "Created: / 02-04-2012 / 11:37:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseNewDialogsEnabled
+    ^ self smallSenseEnabled
+        and:[self at:#smallSenseNewDialogsEnabled ifAbsent:[false]]
+
+    "
+    UserPreferences current smallSenseNewDialogsEnabled.
+    UserPreferences current smallSenseNewDialogsEnabled: true.
+    UserPreferences current smallSenseNewDialogsEnabled: false.   
+    "
+
+    "Created: / 10-05-2014 / 00:05:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 25-11-2014 / 13:06:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense'!
+
+smallSenseNewDialogsEnabled: aBoolean
+
+    ^self at:#smallSenseNewDialogsEnabled put: aBoolean
+
+    "Created: / 10-05-2014 / 00:04:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIndentOnPasteEnabled
+    "Return true if SmallSense indent-on-paste is enabled for Smalltalk language"
+
+    ^self at:#smallSenseSmalltalkIndentOnPasteEnabled ifAbsent:[false]
+
+    "Created: / 19-07-2014 / 00:11:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIndentOnPasteEnabled: aBoolean
+    "Set SmallSense indent-on-paste feature for Smalltalk"
+
+    ^ self at:#smallSenseSmalltalkIndentOnPasteEnabled put: aBoolean
+
+    "
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: true.
+    UserPreferences current smallSenseSmalltalkIndentOnPasteEnabled: false.
+    "
+
+    "Created: / 19-07-2014 / 00:11:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNameMaxLength
+    "Maximum length for iteration variable name. If variable name computed from
+     collection name exeeds the max length, 'each' is used instead."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNameMaxLength ifAbsent:[15"Magic number"]
+
+    "Created: / 04-03-2015 / 08:01:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-03-2015 / 09:39:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNameMaxLength: anInteger
+    "Sets the maximum length for iteration variable name. If variable name computed from
+     collection name exeeds the max length, 'each' is used instead."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNameMaxLength put: anInteger
+
+    "Created: / 04-03-2015 / 08:01:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNamePrefixWithEach
+    "If true, then iteration variable names are prefixed with 'each', i.e.,
+     persons -> eachPerson."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNamePrefixWithEach ifAbsent:[false]
+
+    "Created: / 04-03-2015 / 07:57:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!UserPreferences methodsFor:'accessing-SmallSense-Smalltalk'!
+
+smallSenseSmalltalkIterationVariableNamePrefixWithEach: aBoolean
+    "If true, then iteration variable names are prefixed with 'each', i.e.,
+     persons -> eachPerson."
+
+    ^self at:#smallSenseSmalltalkIterationVariableNamePrefixWithEach put: aBoolean.
+
+    "Created: / 04-03-2015 / 07:57:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VariableNode methodsFor:'queries'!
+
+isGlobalOrPrivateClass
+
+    ^ type == #GlobalVariable or:[type == #PrivateClass]
+
+    "Created: / 27-11-2011 / 16:31:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!VariableNode methodsFor:'navigation-SmallSense'!
+
+navigateToUsing: navigator
+    navigator navigateToVariableNode: self.
+
+    "Created: / 24-09-2013 / 10:04:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!WorkspaceApplication methodsFor:'event handling'!
+
+processShortcut:aKeyPressEvent
+    "a shortcut key event as forwarded from the keyboardProcessor - if there is the
+     shortcut key defined, process the shortcut and return true - otherwise false."
+
+    UserPreferences current smallSenseNewDialogsEnabled ifTrue:[   
+       (aKeyPressEvent key == #OpenNavigator or:[aKeyPressEvent rawKey == #CtrlT and:[(aKeyPressEvent targetView keyboardMap hasBindingFor: #OpenNavigator) not]]) ifTrue:[ 
+            SmallSense::Navigator open.
+            ^ true
+        ].    
+    ].
+    ^ super processShortcut:aKeyPressEvent
+
+    "Created: / 25-01-2015 / 12:18:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 11-02-2015 / 21:33:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense class methodsFor:'documentation'!
+
+extensionsVersion_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/extensions/org/eclipse/jdt/internal/codeassist/complete/CompletionOnFieldType.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,9 @@
+"{ Package: 'stx:goodies/smallsense' }"
+
+!
+
+!(Java classForName:'org.eclipse.jdt.internal.codeassist.complete.CompletionOnFieldType') methodsFor:'* instance *'!
+
+acceptCompletionEngine: engine
+    engine completeOnFieldType: self
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/extensions/org/eclipse/jdt/internal/codeassist/complete/CompletionOnQualifiedNameReference.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,9 @@
+"{ Package: 'stx:goodies/smallsense' }"
+
+!
+
+!(Java classForName:'org.eclipse.jdt.internal.codeassist.complete.CompletionOnQualifiedNameReference') methodsFor:'* instance *'!
+
+acceptCompletionEngine: engine
+    engine completeOnQualifiedNameReference: self.
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/extensions/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleNameReference.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,9 @@
+"{ Package: 'stx:goodies/smallsense' }"
+
+!
+
+!(Java classForName:'org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleNameReference') methodsFor:'* instance *'!
+
+acceptCompletionEngine: engine
+    engine completeOnSingleNameReference: self
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/extensions/org/eclipse/jdt/internal/codeassist/complete/CompletionOnSingleTypeReference.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,9 @@
+"{ Package: 'stx:goodies/smallsense' }"
+
+!
+
+!(Java classForName:'org.eclipse.jdt.internal.codeassist.complete.CompletionOnSingleTypeReference') methodsFor:'* instance *'!
+
+acceptCompletionEngine: engine
+    engine completeOnSingleTypeReference: self
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/extensions/org/eclipse/jdt/internal/compiler/ast/ASTNode.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,11 @@
+"{ Package: 'stx:goodies/smallsense' }"
+
+!
+
+!(Java classForName:'org.eclipse.jdt.internal.compiler.ast.ASTNode') methodsFor:'* instance *'!
+
+acceptCompletionEngine: engine
+    (OperatingSystem getLoginName = 'jv') ifTrue:[
+        Transcript showCR: 'No completion for ', self class name  
+    ].
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/java/extensions/org/eclipse/jdt/internal/compiler/lookup/BaseTypeBinding.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,9 @@
+"{ Package: 'stx:goodies/smallsense' }"
+
+!
+
+!(Java classForName:'org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding') methodsFor:'* instance *'!
+
+displayString
+    ^ simpleName
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lccmake.bat	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,8 @@
+@REM -------
+@REM make using lcc compiler
+@REM type lccmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+make.exe -N -f bc.mak -DUSELCC=1 %*
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lcmake.bat	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,8 @@
+@REM -------
+@REM make using lcc compiler
+@REM type lcmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+make.exe -N -f bc.mak USELCC=1 %1 %2
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libInit.cc	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,111 @@
+/*
+ * $Header$
+ *
+ * DO NOT EDIT
+ * automagically generated from the projectDefinition: stx_goodies_smallsense.
+ */
+#define __INDIRECTVMINITCALLS__
+#include <stc.h>
+
+#ifdef WIN32
+# pragma codeseg INITCODE "INITCODE"
+#endif
+
+#if defined(INIT_TEXT_SECTION) || defined(DLL_EXPORT)
+DLL_EXPORT void _libstx_goodies_smallsense_Init() INIT_TEXT_SECTION;
+DLL_EXPORT void _libstx_goodies_smallsense_InitDefinition() INIT_TEXT_SECTION;
+#endif
+
+void _libstx_goodies_smallsense_InitDefinition(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libstx_goodies_smallsense__DFN", _libstx_goodies_smallsense_InitDefinition, "stx:goodies/smallsense");
+_stx_137goodies_137smallsense_Init(pass,__pRT__,snd);
+
+__END_PACKAGE__();
+}
+
+void _libstx_goodies_smallsense_Init(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libstx_goodies_smallsense", _libstx_goodies_smallsense_Init, "stx:goodies/smallsense");
+_SmallSense__AbstractDIalog_Init(pass,__pRT__,snd);
+_SmallSense__AbstractSearchProcessor_Init(pass,__pRT__,snd);
+_SmallSense__CodeHighlightingService_Init(pass,__pRT__,snd);
+_SmallSense__CodeNavigationService_Init(pass,__pRT__,snd);
+_SmallSense__CompletionContext_Init(pass,__pRT__,snd);
+_SmallSense__CompletionController_Init(pass,__pRT__,snd);
+_SmallSense__CompletionEngine_Init(pass,__pRT__,snd);
+_SmallSense__CompletionResult_Init(pass,__pRT__,snd);
+_SmallSense__CompletionView_Init(pass,__pRT__,snd);
+_SmallSense__CriticsWindow_Init(pass,__pRT__,snd);
+_SmallSense__EditService_Init(pass,__pRT__,snd);
+_SmallSense__EditSupport_Init(pass,__pRT__,snd);
+_SmallSense__Info_Init(pass,__pRT__,snd);
+_SmallSense__Manager_Init(pass,__pRT__,snd);
+_SmallSense__NavigatorStep_Init(pass,__pRT__,snd);
+_SmallSense__PO_Init(pass,__pRT__,snd);
+_SmallSense__ParseTreeIndex_Init(pass,__pRT__,snd);
+_SmallSense__ParseTreeIndexEntry_Init(pass,__pRT__,snd);
+_SmallSense__ParseTreeInspector_Init(pass,__pRT__,snd);
+_SmallSense__SelectorNode_Init(pass,__pRT__,snd);
+_SmallSense__SettingsAppl_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkChecker_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkInferencerParameters_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkLintService_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkParseNodeVisitor_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkParser_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkQuickFixer_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkSyntaxHighlighter_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkUnacceptedMethodEnvironment_Init(pass,__pRT__,snd);
+_SmallSense__TokenPatternMatcher_Init(pass,__pRT__,snd);
+_SmallSense__TokenPatternParser_Init(pass,__pRT__,snd);
+_SmallSense__TokenPatternToken_Init(pass,__pRT__,snd);
+_SmallSense__TokenPatternTokenSet_Init(pass,__pRT__,snd);
+_SmallSense__TokenStream_Init(pass,__pRT__,snd);
+_SmallSense__Type_Init(pass,__pRT__,snd);
+_SmallSense__TypeHolder_Init(pass,__pRT__,snd);
+_stx_137goodies_137smallsense_Init(pass,__pRT__,snd);
+_SmallSense__AbstractJavaCompletionEngine_Init(pass,__pRT__,snd);
+_SmallSense__AbstractListDialog_Init(pass,__pRT__,snd);
+_SmallSense__ClassInfo_Init(pass,__pRT__,snd);
+_SmallSense__ClassPO_Init(pass,__pRT__,snd);
+_SmallSense__ClassSearchProcessor_Init(pass,__pRT__,snd);
+_SmallSense__ClassType_Init(pass,__pRT__,snd);
+_SmallSense__CompositeProcessor_Init(pass,__pRT__,snd);
+_SmallSense__ConstantPO_Init(pass,__pRT__,snd);
+_SmallSense__GenericEditSupport_Init(pass,__pRT__,snd);
+_SmallSense__ImplementorSearchProcessor_Init(pass,__pRT__,snd);
+_SmallSense__JavaEditSupport_Init(pass,__pRT__,snd);
+_SmallSense__JavaImportPO_Init(pass,__pRT__,snd);
+_SmallSense__MethodBindingPO_Init(pass,__pRT__,snd);
+_SmallSense__MethodInfo_Init(pass,__pRT__,snd);
+_SmallSense__MethodPO_Init(pass,__pRT__,snd);
+_SmallSense__PackagePO_Init(pass,__pRT__,snd);
+_SmallSense__PluggablePO_Init(pass,__pRT__,snd);
+_SmallSense__PluggableSearchProcessor_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkCompletionEngine_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkEditSupport_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkInferencer_Init(pass,__pRT__,snd);
+_SmallSense__SmalltalkParseNodeFinder_Init(pass,__pRT__,snd);
+_SmallSense__SnippetPO_Init(pass,__pRT__,snd);
+_SmallSense__UnionType_Init(pass,__pRT__,snd);
+_SmallSense__UnknownType_Init(pass,__pRT__,snd);
+_SmallSense__VariableBindingPO_Init(pass,__pRT__,snd);
+_SmallSense__VariablePO_Init(pass,__pRT__,snd);
+_SmallSense__AbstractJavaCompletionEngineSimple_Init(pass,__pRT__,snd);
+_SmallSense__AbstractSearchDialog_Init(pass,__pRT__,snd);
+_SmallSense__AbstractSelectDialog_Init(pass,__pRT__,snd);
+_SmallSense__GroovyEditSupport_Init(pass,__pRT__,snd);
+_SmallSense__JavaCompletionEngine_Init(pass,__pRT__,snd);
+_SmallSense__JavaConstructorPO_Init(pass,__pRT__,snd);
+_SmallSense__MethodKeywordRestPO_Init(pass,__pRT__,snd);
+_SmallSense__ClassSearchDialog_Init(pass,__pRT__,snd);
+_SmallSense__JavaCompletionEngineSimple_Init(pass,__pRT__,snd);
+_SmallSense__MethodSearchDialog_Init(pass,__pRT__,snd);
+_SmallSense__Navigator_Init(pass,__pRT__,snd);
+_SmallSense__PackageSelectDialog_Init(pass,__pRT__,snd);
+_SmallSense__ProtocolSelectDialog_Init(pass,__pRT__,snd);
+_SmallSense__GroovyCompletionEngineSimple_Init(pass,__pRT__,snd);
+
+_stx_137goodies_137smallsense_extensions_Init(pass,__pRT__,snd);
+__END_PACKAGE__();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/license.txt	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,508 @@
+The SmallSense is available under GNU Lesser General Public License.
+For other licensing options, please contact the SmallSense author at
+jan.vrany { at } fit.cvut.cz.
+
+
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	   How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mingwmake.bat	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,16 @@
+@REM -------
+@REM make using mingw gnu compiler
+@REM type mingwmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+
+@pushd ..\..\rules
+@call find_mingw.bat
+@popd
+make.exe -N -f bc.mak %DEFINES% %USEMINGW_ARG% %*
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/smallsense.rc	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,37 @@
+//
+// DO NOT EDIT
+// automagically generated from the projectDefinition: stx_goodies_smallsense.
+//
+VS_VERSION_INFO VERSIONINFO
+  FILEVERSION     6,2,32767,32767
+  PRODUCTVERSION  6,2,5,0
+#if (__BORLANDC__)
+  FILEFLAGSMASK   VS_FF_DEBUG | VS_FF_PRERELEASE
+  FILEFLAGS       VS_FF_PRERELEASE | VS_FF_SPECIALBUILD
+  FILEOS          VOS_NT_WINDOWS32
+  FILETYPE        VFT_DLL
+  FILESUBTYPE     VS_USER_DEFINED
+#endif
+
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    BEGIN
+      VALUE "CompanyName", "Jan Vrany\0"
+      VALUE "FileDescription", "Smalltalk/X IDE Productivity Tool (LIB)\0"
+      VALUE "FileVersion", "6.2.32767.32767\0"
+      VALUE "InternalName", "stx:goodies/smallsense\0"
+      VALUE "LegalCopyright", "Copyright Jan Vrany 2013-2014\0"
+      VALUE "ProductName", "SmallSense\0"
+      VALUE "ProductVersion", "6.2.5.0\0"
+      VALUE "ProductDate", "Sat, 21 Feb 2015 22:50:34 GMT\0"
+    END
+
+  END
+
+  BLOCK "VarFileInfo"
+  BEGIN                               //  Language   |    Translation
+    VALUE "Translation", 0x409, 0x4E4 // U.S. English, Windows Multilingual
+  END
+END
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stx_goodies_smallsense.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,571 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: Smalltalk }"
+
+LibraryDefinition subclass:#stx_goodies_smallsense
+	instanceVariableNames:''
+	classVariableNames:'Swizzled'
+	poolDictionaries:''
+	category:'* Projects & Packages *'
+!
+
+!stx_goodies_smallsense class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2015 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+"
+!
+
+documentation
+"
+    Package documentation:
+
+    Jan Vrany's productivity tools for the Smalltalk code editor.
+    Includes different code completion engine, bracket insertion and other enhancements.
+"
+! !
+
+!stx_goodies_smallsense class methodsFor:'accessing - tests'!
+
+excludedFromTestSuite
+    "List of testcases and/or tests excluded from testsuite.
+     Entries maybe ClassName or #(ClassName testName)
+    "
+    ^ #(
+        #'SmallSense::BaseTestClass'
+        #'SmallSense::TestCase'
+        #'SmallSense::FinderTests'
+        #'SmallSense::RecognizerTests'
+        #'SmallSense::SmalltalkParserTests'
+    )
+
+    "Created: / 23-05-2014 / 12:49:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense class methodsFor:'description'!
+
+excludedFromPreRequisites
+    "list all packages which should be ignored in the automatic
+     preRequisites scan. See #preRequisites for more."
+
+    ^ #(
+    )
+!
+
+mandatoryPreRequisites
+    "list packages which are mandatory as a prerequisite.
+     This are packages containing superclasses of my classes and classes which
+     are extended by myself.
+     They are mandatory, because we need these packages as a prerequisite for loading and compiling.
+     This method is generated automatically,
+     by searching along the inheritance chain of all of my classes."
+
+    ^ #(
+        #'stx:goodies/refactoryBrowser/helpers'    "BrowserEnvironment - superclass of SmallSense::SmalltalkUnacceptedMethodEnvironment"
+        #'stx:goodies/refactoryBrowser/lint'    "RBBasicLintRule - extended"
+        #'stx:goodies/refactoryBrowser/parser'    "RBBlockNode - extended"
+        #'stx:goodies/regex'    "Regex::RxCharSetParser - superclass of SmallSense::TokenPatternParser::TokenSpecParser"
+        #'stx:goodies/sunit'    "TestAsserter - superclass of SmallSense::AbstractTestCase"
+        #'stx:libbasic'    "Autoload - superclass of SmallSense::AbstractJavaCompletionEngineTests"
+        #'stx:libcomp'    "AbstractSyntaxHighlighter - superclass of SmallSense::SmalltalkParser"
+        #'stx:libhtml'    "HTMLDocumentFrame - extended"
+        #'stx:libtool'    "AbstractSettingsApplication - superclass of SmallSense::SettingsAppl"
+        #'stx:libview'    "DisplaySurface - extended"
+        #'stx:libview2'    "ApplicationModel - extended"
+        #'stx:libwidg'    "DialogBox - extended"
+        #'stx:libwidg2'    "HierarchicalItem - superclass of SmallSense::ClassPO"
+    )
+!
+
+referencedPreRequisites
+    "list packages which are a prerequisite, because they contain
+     classes which are referenced by my classes.
+     We do not need these packages as a prerequisite for compiling or loading,
+     however, a class from it may be referenced during execution and having it
+     unloaded then may lead to a runtime doesNotUnderstand error, unless the caller
+     includes explicit checks for the package being present.
+     This method is generated automatically,
+     by searching all classes (and their packages) which are referenced by my classes."
+
+    ^ #(
+        #'stx:libbasic2'    "BackgroundJob - referenced by SmallSense::AbstractListDialog>>initialize"
+        #'stx:libbasic3'    "ChangeSet - referenced by RBContainsSmalltalkXEOLCommentRule>>fixes:"
+        #'stx:libjava'    "Java - referenced by SmallSense::JavaCompletionEngine>>complete"
+        #'stx:libjava/tools'    "GroovyScanner - referenced by SmallSense::GroovyCompletionEngineSimple>>scannerClass"
+    )
+!
+
+subProjects
+    "list packages which are known as subprojects.
+     The generated makefile will enter those and make there as well.
+     However: they are not forced to be loaded when a package is loaded;
+     for those, redefine requiredPrerequisites"
+
+    ^ #(
+    )
+! !
+
+!stx_goodies_smallsense class methodsFor:'description - contents'!
+
+classNamesAndAttributes
+    "lists the classes which are to be included in the project.
+     Each entry in the list may be: a single class-name (symbol),
+     or an array-literal consisting of class name and attributes.
+     Attributes are: #autoload or #<os> where os is one of win32, unix,..."
+
+    ^ #(
+        "<className> or (<className> attributes...) in load order"
+        #'SmallSense::AbstractDIalog'
+        #'SmallSense::AbstractSearchProcessor'
+        (#'SmallSense::AbstractTestCase' autoload)
+        #'SmallSense::CodeHighlightingService'
+        #'SmallSense::CodeNavigationService'
+        #'SmallSense::CompletionContext'
+        #'SmallSense::CompletionController'
+        #'SmallSense::CompletionEngine'
+        #'SmallSense::CompletionResult'
+        #'SmallSense::CompletionView'
+        #'SmallSense::CriticsWindow'
+        #'SmallSense::EditService'
+        #'SmallSense::EditSupport'
+        #'SmallSense::Info'
+        #'SmallSense::Manager'
+        #'SmallSense::NavigatorStep'
+        #'SmallSense::PO'
+        #'SmallSense::ParseTreeIndex'
+        #'SmallSense::ParseTreeIndexEntry'
+        #'SmallSense::ParseTreeInspector'
+        #'SmallSense::SelectorNode'
+        #'SmallSense::SettingsAppl'
+        #'SmallSense::SmalltalkChecker'
+        #'SmallSense::SmalltalkInferencerParameters'
+        #'SmallSense::SmalltalkLintService'
+        #'SmallSense::SmalltalkParseNodeVisitor'
+        #'SmallSense::SmalltalkParser'
+        #'SmallSense::SmalltalkQuickFixer'
+        #'SmallSense::SmalltalkSyntaxHighlighter'
+        #'SmallSense::SmalltalkUnacceptedMethodEnvironment'
+        #'SmallSense::TokenPatternMatcher'
+        #'SmallSense::TokenPatternParser'
+        #'SmallSense::TokenPatternToken'
+        #'SmallSense::TokenPatternTokenSet'
+        #'SmallSense::TokenStream'
+        #'SmallSense::Type'
+        #'SmallSense::TypeHolder'
+        #'stx_goodies_smallsense'
+        #'SmallSense::AbstractJavaCompletionEngine'
+        #'SmallSense::AbstractListDialog'
+        #'SmallSense::ClassInfo'
+        #'SmallSense::ClassPO'
+        #'SmallSense::ClassSearchProcessor'
+        #'SmallSense::ClassType'
+        #'SmallSense::CompositeProcessor'
+        #'SmallSense::ConstantPO'
+        (#'SmallSense::EditSupportTests' autoload)
+        #'SmallSense::GenericEditSupport'
+        #'SmallSense::ImplementorSearchProcessor'
+        #'SmallSense::JavaEditSupport'
+        #'SmallSense::JavaImportPO'
+        #'SmallSense::MethodBindingPO'
+        #'SmallSense::MethodInfo'
+        #'SmallSense::MethodPO'
+        #'SmallSense::PackagePO'
+        #'SmallSense::PluggablePO'
+        #'SmallSense::PluggableSearchProcessor'
+        #'SmallSense::SmalltalkCompletionEngine'
+        #'SmallSense::SmalltalkEditSupport'
+        #'SmallSense::SmalltalkInferencer'
+        #'SmallSense::SmalltalkParseNodeFinder'
+        #'SmallSense::SnippetPO'
+        #'SmallSense::UnionType'
+        #'SmallSense::UnknownType'
+        #'SmallSense::VariableBindingPO'
+        #'SmallSense::VariablePO'
+        #'SmallSense::AbstractJavaCompletionEngineSimple'
+        #'SmallSense::AbstractSearchDialog'
+        #'SmallSense::AbstractSelectDialog'
+        #'SmallSense::GroovyEditSupport'
+        #'SmallSense::JavaCompletionEngine'
+        #'SmallSense::JavaConstructorPO'
+        #'SmallSense::MethodKeywordRestPO'
+        (#'SmallSense::SmalltalkEditSupportTests' autoload)
+        #'SmallSense::ClassSearchDialog'
+        #'SmallSense::JavaCompletionEngineSimple'
+        #'SmallSense::MethodSearchDialog'
+        #'SmallSense::Navigator'
+        #'SmallSense::PackageSelectDialog'
+        #'SmallSense::ProtocolSelectDialog'
+        #'SmallSense::GroovyCompletionEngineSimple'
+        (#'SmallSense::AbstractJavaCompletionEngineTests' autoload)
+        (#'SmallSense::BaseTestClass' autoload)
+        (#'SmallSense::CompletionEngineTests' autoload)
+        (#'SmallSense::FinderTests' autoload)
+        (#'SmallSense::GroovyCompletionEngineSimpleTests' autoload)
+        (#'SmallSense::JavaCompletionEngineEnvironmentResource' autoload)
+        (#'SmallSense::JavaCompletionEngineTests' autoload)
+        (#'SmallSense::JavaEditSupportTests' autoload)
+        (#'SmallSense::RecognizerTests' autoload)
+        (#'SmallSense::SmalltalkCompletionEngineTests' autoload)
+        (#'SmallSense::SmalltalkParserTests' autoload)
+        (#'SmallSense::TestCase' autoload)
+        (#'SmallSense::TokenPatternMatcherTests' autoload)
+    )
+!
+
+extensionMethodNames
+    "list class/selector pairs of extensions.
+     A correponding method with real names must be present in my concrete subclasses"
+
+    ^ #(
+        ParseNode isSelector
+        AssignmentNode childNamesAndValuesDo:
+        AssignmentNode inferedType
+        AssignmentNode inferedType:
+        MessageNode childNamesAndValuesDo:
+        ParseErrorNode childNamesAndValuesDo:
+        ParseNode childNamesAndValuesDo:
+        ParseNode inferedType
+        ParseNode inferedType:
+        PrimaryNode childNamesAndValuesDo:
+        StatementNode childNamesAndValuesDo:
+        StatementNode inferedType
+        StatementNode inferedType:
+        UserPreferences smallSenseEnabled
+        UserPreferences smallSenseEnabled:
+        VariableNode isGlobalOrPrivateClass
+        'ConfigurableFeatures class' hasSmallSenseEnabled
+        UserPreferences smallSenseBackgroundLintEnabled
+        UserPreferences smallSenseBackgroundLintEnabled:
+        RBLintRule fixes:
+        RBTransformationRule fixes:
+        UserPreferences smallSenseBackgroundTypingEnabled
+        UserPreferences smallSenseBackgroundTypingEnabled:
+        HTMLDocumentView doQuickFix:
+        'Tools::CodeHighlightingService class' new
+        BlockNode childNamesAndValuesDo:
+        'Tools::CodeNavigationService class' new
+        ParseNode navigateToUsing:
+        MessageNode navigateToUsing:
+        VariableNode navigateToUsing:
+        EditTextView autoIndent
+        #'Tools::NewSystemBrowser' #'searchCompletionBlock_SmallSense'
+        #'Tools::NewSystemBrowser' smallSenseSearchCompletion:
+        #'Tools::NewSystemBrowser' smallSenseSearchCompletionBlock
+        #'Tools::NewSystemBrowser' smallSenseSearchCompletionEntryForClass:showPrefix:
+        #'Tools::NewSystemBrowser' smallSenseSearchCompletionNewForClass:
+        PrimitiveNode inferedType
+        UserPreferences smallSenseCompleteIfUnambiguous
+        UserPreferences smallSenseCompleteIfUnambiguous:
+        UserPreferences smallSenseCompletionEnabled
+        UserPreferences smallSenseCompletionEnabled:
+        ReturnNode childNamesAndValuesDo:
+        'Tools::NewSystemBrowser class' #'stx_goodies_smallsense_askForClassToSearch:single:msgTail:resources:filter:forBrowser:thenDo:'
+        UserPreferences smallSenseNewDialogsEnabled
+        UserPreferences smallSenseNewDialogsEnabled:
+        UserPreferences smallSenseSmalltalkIndentOnPasteEnabled
+        UserPreferences smallSenseSmalltalkIndentOnPasteEnabled:
+        EditTextViewCompletionSupport isCompletionViewShown
+        #'Tools::NavigationState' #'stx_goodies_smallsense_selectedClasses'
+        Method inspector2TabSTXParseTreeInspector
+        ParseNode inspector2TabSTXParseTreeInspector
+        Parser inspector2TabSTXParseTreeInspector
+        Method inspector2TabRBParseTreeInspector
+        RBBlockNode childNamesAndValuesDo:
+        RBMethodNode childNamesAndValuesDo:
+        RBProgramNode childNamesAndValuesDo:
+        RBProgramNode endPosition
+        RBProgramNode startPosition
+        RBContainsSmalltalkXEOLCommentRule fixes:
+        'DialogBox class' #'stx_goodies_smallsense_requestProject:from:initialAnswer:suggestions:'
+        'Tools::CodeCompletionService class' new
+        #'Tools::LintService' buttonPress:x:y:in:
+        #'Tools::LintService' showInfoWindowForLine:
+        InspectorView preRealize
+        #'Tools::NewSystemBrowser' #'stx_goodies_smallsense_askForMethodCategory:title:okLabel:list:recentList:initialAnswer:'
+        #'Tools::NewSystemBrowser' searchMenuOpenNavigatorOnDeclarations
+        DebugView processShortcut:
+        #'Tools::Inspector2' processShortcut:
+        WorkspaceApplication processShortcut:
+        #'Tools::NewSystemBrowser' processShortcut:
+        UserPreferences smallSenseSmalltalkIterationVariableNameMaxLength
+        UserPreferences smallSenseSmalltalkIterationVariableNameMaxLength:
+        UserPreferences smallSenseSmalltalkIterationVariableNamePrefixWithEach
+        UserPreferences smallSenseSmalltalkIterationVariableNamePrefixWithEach:
+        UserPreferences smallSenseElectricEditSupportEnabled
+        UserPreferences smallSenseElectricEditSupportEnabled:
+    )
+! !
+
+!stx_goodies_smallsense class methodsFor:'description - project information'!
+
+applicationIconFileName
+    "Return the name (without suffix) of an icon-file (the app's icon); will be included in the rc-resource file"
+
+    ^ nil
+    "/ ^ self applicationName
+!
+
+companyName
+    "Return a companyname which will appear in <lib>.rc"
+
+    ^ 'Jan Vrany'
+
+    "Modified: / 17-07-2014 / 22:57:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+description
+    "Return a description string which will appear in vc.def / bc.def"
+
+    ^ 'Smalltalk/X IDE Productivity Tool'
+
+    "Modified: / 17-07-2014 / 23:06:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+legalCopyright
+    "Return a copyright string which will appear in <lib>.rc"
+
+    ^ 'Copyright Jan Vrany 2013-2014'
+
+    "Modified: / 17-07-2014 / 22:57:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+productName
+    "Return a product name which will appear in <lib>.rc"
+
+    ^ 'SmallSense'
+
+    "Modified: / 17-07-2014 / 23:06:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense class methodsFor:'description - svn'!
+
+svnRepositoryUrlString
+    "Return a SVN repository URL of myself.
+     (Generated since 2011-04-08)
+    "
+
+    ^ '$URL: https://vranyj1@swing.fit.cvut.cz/svn/stx/libtool/branches/jv/smallsense/stx_goodies_smallsense.st $'
+!
+
+svnRevisionNr
+    "Return a SVN revision number of myself.
+     This number is updated after a commit"
+
+    ^ "$SVN-Revision:"'7962            '"$"
+! !
+
+!stx_goodies_smallsense class methodsFor:'swizzling'!
+
+swizzle
+    "Swizzle all methods annotated as <swizzle:>"
+
+
+    Swizzled == true ifTrue:[ ^ self ].
+    ParserFlags initialize.
+    self extensionMethods do:[:m |
+        [
+            self swizzle: m.
+        ] on: Error do:[:ex |
+            Logger error: 'Cannot swizzle %1: %2' with: m selector with: ex description.
+            Debugger enter.
+        ].
+    ].
+    Swizzled := true.
+
+
+    "
+    stx_goodies_smallsense swizzle
+    Swizzled := false.
+
+    self extensionMethods select:[:m | m notNil and:[ (m annotationAt: #swizzle:) notNil or:[(m annotationAt: #swizzle:checksum:) notNil ] ] ]
+    "
+
+    "Created: / 19-08-2013 / 14:54:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-12-2014 / 23:36:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+swizzle: method
+    "Swizzle the method if it is annotated by <swizzle:> annotation"
+
+    | annotation |
+
+
+    annotation := method annotationAt: #swizzle:.
+    annotation notNil ifTrue:[
+    	self swizzle: method as: (annotation argumentAt: 1).
+        ^ self
+    ].
+    annotation := method annotationAt: #swizzle:checksum:.
+    annotation notNil ifTrue:[
+        self swizzle: method as: (annotation argumentAt: 1) checksum: (annotation argumentAt: 2)
+    ].
+
+    "Created: / 19-08-2013 / 14:53:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-05-2014 / 00:23:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+swizzle: swizzlingMethod as: selector
+    "Given an extension method, swizzle it into method's class
+     under given selector."
+
+    ^ self swizzle: swizzlingMethod as: selector checksum: nil
+
+    "Created: / 19-08-2013 / 14:01:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-05-2014 / 00:24:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+swizzle: swizzlingMethod as: selector checksum: expectedSHA
+    "Given an extension method, swizzle it into method's class
+     under given selector.
+
+     If `expectedSHA` is not nil, compare SHA1 hashes of swizzledMethod
+     source and issue a warning when checksum does not match - which
+     means somebody changed that method meanwhile and we should
+     validate/update swizzlling method"
+
+    | cls shadowedMethod shadowedMethodSHA shadowedMethodProjectDefinition shadowedMethodCopy swizzledForwarderMethodSource swizzledForwarderMethod |
+
+    cls := swizzlingMethod mclass.
+    shadowedMethod := cls compiledMethodAt: selector.
+    shadowedMethod isNil ifTrue:[
+        "/ Oops, method gone?
+        self breakPoint: #jv.
+        ^ self.
+    ].
+
+    self assert: swizzlingMethod numArgs == shadowedMethod numArgs.
+    self assert: (swizzlingMethod selector startsWith: self name , '_').
+
+    expectedSHA notNil ifTrue:[
+        | src |
+
+        src := shadowedMethod source.
+        src notNil ifTrue:[
+            shadowedMethodSHA := SHA1Stream new nextPutAll: src; hashValue.
+            shadowedMethodSHA = expectedSHA ifFalse:[
+                Logger error: 'Overwritten method checksum for: %1 does not match %2' with: shadowedMethod selector with: expectedSHA
+            ].
+        ].
+    ].
+
+    "/ Save shadowedMethod to project...
+    shadowedMethodProjectDefinition := ProjectDefinition definitionClassForPackage: shadowedMethod package.
+    shadowedMethodProjectDefinition rememberOverwrittenMethod:shadowedMethod inClass: shadowedMethod mclass.
+
+
+    swizzledForwarderMethodSource := String streamContents:[ :s |
+    	| selector keywords |
+
+    	selector := shadowedMethod selector.
+    	selector numArgs > 0 ifTrue:[
+    	    keywords := selector keywords.
+            keywords withIndexDo:[ :keyword :index |
+                s nextPutAll: keyword; space; nextPutAll: 'arg'; nextPutAll: index printString; space.
+            ].
+    	] ifFalse:[
+    	    s nextPutAll: selector; cr.
+    	].
+
+        s cr.
+        s nextPutLine: '    "This method has been swizled by SmallSense, forwarding to SmallSense implementation"'.
+        s nextPutAll:  '    ^ self '; nextPutAll: self name; nextPut: $_.
+        selector numArgs > 0 ifTrue:[
+            keywords withIndexDo:[ :keyword :index |
+                s nextPutAll: keyword; space; nextPutAll: 'arg'; nextPutAll: index printString; space
+            ].
+    	] ifFalse:[
+    	    s nextPutAll: selector.
+    	].
+    	s cr.
+
+    ].
+
+    "/ Stdout nextPutAll: '>>>'; nextPutLine: selector.
+    "/ Stdout nextPutLine: '----'.
+    "/ Stdout nextPutLine: swizzledForwarderMethodSource.
+    "/ Stdout nextPutLine: '----'.
+
+
+    shadowedMethodCopy := shadowedMethod copy.
+    shadowedMethodCopy setPackage: #__swizzled__.
+    shadowedMethodCopy setCategory: shadowedMethod category.
+    shadowedMethodCopy source: ((shadowedMethod package copyReplaceAll: $: with: $_) replaceAll: $/ with: $_) , '_' , shadowedMethod source.
+    shadowedMethod mclass
+        basicAddSelector: (((shadowedMethod package copyReplaceAll: $: with: $_) replaceAll: $/ with: $_) , '_' , shadowedMethod selector) asSymbol
+        withMethod: shadowedMethodCopy.
+
+
+    "/ Install the swizzled method
+    "/ Stdout nextPutLine: '^^^ Compiling'.
+    swizzledForwarderMethod := ByteCodeCompiler compile: swizzledForwarderMethodSource forClass: cls install: false.
+    swizzledForwarderMethod category: shadowedMethod category.
+    swizzledForwarderMethod package: shadowedMethodCopy package.
+    cls basicAddSelector:selector withMethod:swizzledForwarderMethod.
+
+    "/ Stdout nextPutLine: '^^^ Compiled'.
+
+    "Created: / 10-05-2014 / 00:23:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 07-10-2014 / 15:09:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+swizzled
+    "Return true, if methods has been swizled"
+
+    ^ Swizzled == true
+
+    "Created: / 12-01-2015 / 06:53:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/smallsense/stx_goodies_smallsense.st,v 1.2 2015-02-03 22:23:33 cg Exp $'
+!
+
+version_CVS
+    ^ '$Path: stx/goodies/smallsense/stx_goodies_smallsense.st, Version: 1.0, User: cg, Time: 2015-02-03T23:23:58.941+01$'
+!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+    ^ '$Id: stx_goodies_smallsense.st,v 1.2 2015-02-03 22:23:33 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vcmake.bat	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,20 @@
+@REM -------
+@REM make using Microsoft Visual C compiler
+@REM type vcmake, and wait...
+@REM do not edit - automatically generated from ProjectDefinition
+@REM -------
+
+@if not defined VSINSTALLDIR (
+    pushd ..\..\rules
+    call vcsetup.bat
+    popd
+)
+@SET DEFINES=
+@REM Kludge got Mercurial, cannot be implemented in Borland make
+@FOR /F "tokens=*" %%i in ('hg root') do SET HGROOT=%%i
+@IF "%HGROOT%" NEQ "" SET DEFINES=%DEFINES% "-DHGROOT=%HGROOT%"
+make.exe -N -f bc.mak -DUSEVC=1 %DEFINES% %*
+
+
+
+