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 (current diff)
parent 833 297eb38e4eee (diff)
child 835 e6c018be0875
Merged Jakub Nesveda's refactoring_custom into master.
.hgtags
--- a/.hgtags	Sat May 09 10:22:57 2015 +0100
+++ b/.hgtags	Sun Jun 14 09:54:32 2015 +0100
@@ -1,4 +1,5 @@
 a27be88be57fe3d2ec05f2c08cf9baa9f22c7a14 expecco_2_7_0
+ce462903d43b4e1396691c65a4c24875dc1c4b16 thesis_submission
 a27be88be57fe3d2ec05f2c08cf9baa9f22c7a14 expecco_2_7_0
 feba6ee5c81409691496b92dabd87217d18adf11 expecco_2_7_0
 feba6ee5c81409691496b92dabd87217d18adf11 expecco_2_7_0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Makefile	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,21 @@
+#
+# 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.
+#
+
+.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/docs/online/README.txt	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,3 @@
+This directory contains html documentation which
+is inpired by Smalltalk/X 'online' docs found here
+  http://live.exept.de/doc/online/english/TOP.html
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/online/english/programming/refactoring_custom-getting-started.html	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,149 @@
+<HTML>
+
+<HEAD>
+<TITLE>Smalltalk/X Programmers guide - API for custom code generators and refactorings - getting started</Title>
+</HEAD>
+
+<BODY>
+
+<A NOPRINT HREF="refactoring_custom-installation.html">   <IMG SRC="../../icons/DocsLeftArrow.gif" ALT="[prev]"></A>
+<A NOPRINT HREF="refactoring_custom.html">   <IMG SRC="../../icons/DocsUpArrow.gif" ALT="[up]"></A>
+<A NOPRINT HREF="#">  <IMG SRC="../../icons/DocsRightArrow.gif" ALT="[next]"></A>
+
+<H1>API for custom code generators and refactorings - getting started</H1>
+
+<p>
+This page describes how to create new code generator class.
+Further documentation can be found inside classes and methods comments.
+Existing code generator/refactoring classes has class (static) method "description"
+which should reveal the class purpose.
+</p>
+
+
+<h2>How to create new code generator class</h2>
+
+<p>
+Right-click somewhere in the class list within system browser and click
+on "Generate - Custom -&gt; New Code Generator". Insert some class name
+and click on Ok button. Now you should have new class created with generated
+method stubs containg "self shouldImplement".
+</p> 
+
+<h2>Implement required methods</h2>
+
+<p>
+Here we show a few examples how required methods can be implemented.
+Each method has documentation comment which describes its purpose.
+</p>
+
+<h3>Class (static) methods</h3>
+
+<pre class="code-snippet">
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Mark class as abstract'
+    
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Mark class as abstract (by implementing class method #isAbstract)'
+
+availableInContext:aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ aCustomContext selectedClasses notEmptyOrNil
+
+availableInPerspective:aCustomPerspective
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    "Allows to locate generator in class/method/package/... context sub-menu.
+    See class CustomPerspective and its subclasses."
+    ^ aCustomPerspective isClassPerspective
+</pre>
+
+<h3>Instance methods</h3>
+
+<pre class="code-snippet">
+buildInContext: aCustomContext
+    "Creates a method isAbstract for selected classes"
+    
+    | classes |
+
+    classes := aCustomContext selectedClasses.
+    classes do: [ :class |
+        | metaclass className |
+
+        metaclass := class theMetaclass.
+        className := class theNonMetaclass name.
+
+        (metaclass includesSelector: #isAbstract) ifFalse:[  
+            self compile: ('isAbstract
+    ^ self == %1' bindWith: className) forClass: metaclass inCategory: 'testing'
+        ].   
+    ]
+    
+configureInContext:aCustomContext
+    "Optional method which is called only in interactive mode.
+    Allows to open the dialog-box in which an user can enter custom values.
+    This particular dialog asks for test method name."
+
+    aCustomContext selectedMethods do:[:selectedMethod |
+        | selector |
+
+        selector := selectedMethod selector asSymbol.
+        (testMethodSelectors includesKey: selector) ifFalse: [ 
+            testMethodSelectors 
+                at: selector 
+                put: (self createTestMethodSelectorFor: selector).
+        ].
+
+        dialog 
+            addSelectorNameEntryOn:(DictionaryAdaptor new
+                                        subject:testMethodSelectors; 
+                                        aspect:selector)
+            labeled:selector asString
+            validateBy:nil.
+    ].
+
+    dialog addButtons.
+    dialog open.
+</pre>
+
+<h2>How to create new refactoring class</h2>
+
+<p>
+The process is same as described for code generator class, but you need to
+select "Generate -&gt; New Refactoring" in context menu instead.
+Code example below uses code expression replacements which is
+well documented in
+<a href="http://live.exept.de/doc/online/english/help/Browser/RBSearchPatterns.html">Code Search Patterns</a>.
+</p>
+
+<pre class="code-snippet">
+buildInContext: aCustomContext
+    "Performs a refactoring within given context scope.
+    This code replaces selected code in code editor with
+    translation call."
+
+    refactoryBuilder 
+          replace:'`@expression'
+          with:'(resources string: (`@expression))'
+          inContext:aCustomContext
+</pre>
+
+<HR>
+<P>
+<IMG NOPRINT ALIGN=middle SRC="../../icons/stx.gif">
+
+</BODY>
+</HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/online/english/programming/refactoring_custom-installation.html	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,80 @@
+<HTML>
+
+<HEAD>
+<TITLE>Smalltalk/X Programmers guide - API for custom code generators and refactorings - installation</TITLE>
+</HEAD>
+
+<BODY>
+
+<A NOPRINT HREF="refactoring_custom.html">   <IMG SRC="../../icons/DocsLeftArrow.gif" ALT="[prev]"></A>
+<A NOPRINT HREF="refactoring_custom.html">   <IMG SRC="../../icons/DocsUpArrow.gif" ALT="[up]"></A>
+<A NOPRINT HREF="refactoring_custom-getting-started.html">  <IMG SRC="../../icons/DocsRightArrow.gif" ALT="[next]"></A>
+
+<H1>API for custom code generators and refactorings - installation</H1>
+
+<h2>Requirements</h2>
+
+<p>
+<b>1. Smalltalk/X</b><br>
+You need recent <a href="http://swing.fit.cvut.cz/projects/stx-goodies/wiki/SmalltalkX">Smalltalk/X jv-branch</a> downloaded and 
+installed on your computer. Package is not tested and maintained on official eXept
+Smalltalk/X distribution downloaded from <a href="http://www.exept.de">http://www.exept.de</a>.
+</p>
+
+<p>
+<b>2. Package source files</b><br>
+
+You need to download package from Bitbucket repository
+<a href="https://bitbucket.org/jnesveda/refactoring_custom">jnesveda/refactoring_custom</a>.
+You can download it via
+<a href="http://mercurial.selenic.com/">Mercurial</a>
+command "hg clone url/from/the/link/above" or by clicking on cloud icon in the
+left bar titled with "Downloads".
+</p>
+
+<h2>Installation</h2>
+
+<p>
+Add downloaded source files to folder named "jn/refactoring_custom" which needs
+to be located under your package path (easiest is to put it just in lib/smalltalkx/6.2.5/packages
+where 6.2.5 is STX version). Now run STX, open system browser and click on
+top menu items named "View -&gt; Package". You should see new package named
+jn/refactoring_custom. Right-click on it and select "Load".
+<pre class="code-snippet">
+"To see whats you package path write following line somewhere in STX
+(code editor,launcher text-box), select it, rigt-click and choose Inspect."
+Smalltalk packagePath.
+"This will add a folder as package path"
+Smalltalk packagePath add: 'C:\path\to\your\packages'.
+</pre>
+</p>
+
+<p>
+If everything went well then you can select some class in the system browser,
+right-click on it and now you should see 2 new menu items "Refactor - Custom",
+"Generate - Custom". However, many troubles can happen during package loading.
+Subpackage "patches" has to also properly loaded, but can happen that it wont
+load with described procedure. There are many other possibilities how to load
+classes. You can try one of these if regular way fails (you will see classes marked
+as unloaded or you wont see them):
+<ul>
+	<li>Load classes one-by-one by double clicking on them</li>
+	<li>Click on View -&gt; Category in the system browser, select category,
+	right-click on it and click on "Special -&gt; Load"</li>
+	<li>Open file browser, locate the source files, select them, right-click
+	on it and click on FileIn</li>
+	<li>Paste "Smalltalk loadPackage: 'jn:refactoring_custom'" somewhere (e.g. launcher dialog),
+	select it, right-click on it and click on "DoIt" in the menu</li>
+</ul>
+Finally you can run tests using test runner from launcher to see if everything
+works as expected. You can check the test results against the newest STX-JV branch version
+in <a href="https://swing.fit.cvut.cz/jenkins/job/custom_refactorings_reports/">Jenkins job</a>,
+but this will be most probably removed when this project will be outdated.
+</p>
+
+<HR>
+<P>
+<IMG NOPRINT ALIGN=middle SRC="../../icons/stx.gif">
+
+</BODY>
+</HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/online/english/programming/refactoring_custom.html	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,48 @@
+<HTML>
+
+<HEAD>
+<TITLE>Smalltalk/X Programmers guide - API for custom code generators and refactorings</TITLE>
+</HEAD>
+
+<BODY>
+
+<A NOPRINT HREF="tdv.html">     <IMG SRC="../../icons/DocsLeftArrow.gif" ALT="[prev]"></A>
+<A NOPRINT HREF="TOP.html">   <IMG SRC="../../icons/DocsUpArrow.gif" ALT="[up]"></A>
+<A NOPRINT HREF="refactoring_custom-installation.html">   <IMG SRC="../../icons/DocsRightArrow.gif" ALT="[next]"></A>
+
+<H1>API for custom code generators and refactorings</H1>
+
+<H2>Overview</H2>
+
+<p>
+API for programmers who would like to create their own code generators
+or refactorings in Smalltalk/X environment. This API is intended to be
+more user-friendly than existing possibilities in STX version 6.2.5 .
+The documentation here is not very detailed and further reading can be
+found in <A HREF="https://bitbucket.org/jnesveda/refactoring_custom_thesis">bachelor's thesis text</A>
+(BP_Nesveda_Jakub_2015.pdf), especially chapter "API in a nutshell" describes
+how to write code generators or refactoring.
+</p>
+
+<H2>Contents</H2>
+
+<OL>
+    <LI><A HREF="refactoring_custom-installation.html">Installation</A></LI>
+    <LI><A HREF="refactoring_custom-getting-started.html">Getting started</A></LI>
+</OL>
+
+<H2>Origin/Authors</H2>
+Authors:
+<BR>
+<UL>
+  <LI>Jan Vrany (eXept, SWING Research Group, Czech Technical University in Prague)</LI>
+  <LI>Jakub Nesveda (Czech Technical University in Prague, Faculty of Information Technology, Department of Software Engineering)</LI>
+</UL>
+
+<HR>
+<P>
+<IMG NOPRINT ALIGN=middle SRC="../../icons/stx.gif">
+
+
+</BODY>
+</HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/Make.proto	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,204 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+#
+# 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/changes -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers -I$(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser -I$(INCLUDE_TOP)/stx/goodies/smallsense -I$(INCLUDE_TOP)/stx/goodies/sunit -I$(INCLUDE_TOP)/stx/libbasic -I$(INCLUDE_TOP)/stx/libbasic3 -I$(INCLUDE_TOP)/stx/libcomp -I$(INCLUDE_TOP)/stx/libjava -I$(INCLUDE_TOP)/stx/libjava/tools -I$(INCLUDE_TOP)/stx/libjavascript -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_refactoring_custom
+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::  
+
+
+
+
+
+
+# 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_refactoring_custom.$(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 $(TOP)/libbasic && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/goodies/refactoryBrowser/changes && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/goodies/refactoryBrowser/helpers && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/goodies/refactoryBrowser/parser && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libbasic2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libbasic3 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libcomp && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libui && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libview && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libview2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/goodies/sunit && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libwidg && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/libwidg2 && $(MAKE) "CFLAGS_LOCAL=$(GLOBALDEFINES)"
+	cd $(TOP)/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__CustomChangeManager.$(O) SmallSense__CustomChangeManager.$(H): SmallSense__CustomChangeManager.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomClassQuery.$(O) SmallSense__CustomClassQuery.$(H): SmallSense__CustomClassQuery.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoring.$(O) SmallSense__CustomCodeGeneratorOrRefactoring.$(H): SmallSense__CustomCodeGeneratorOrRefactoring.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomContext.$(O) SmallSense__CustomContext.$(H): SmallSense__CustomContext.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDialog.$(O) SmallSense__CustomDialog.$(H): SmallSense__CustomDialog.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomManager.$(O) SmallSense__CustomManager.$(H): SmallSense__CustomManager.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMenuBuilder.$(O) SmallSense__CustomMenuBuilder.$(H): SmallSense__CustomMenuBuilder.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMock.$(O) SmallSense__CustomMock.$(H): SmallSense__CustomMock.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNamespace.$(O) SmallSense__CustomNamespace.$(H): SmallSense__CustomNamespace.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBNamespace.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomParseTreeRewriter.$(O) SmallSense__CustomParseTreeRewriter.$(H): SmallSense__CustomParseTreeRewriter.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/ParseTreeRewriter.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/ParseTreeSearcher.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/ParseTreeSourceRewriter.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPerspective.$(O) SmallSense__CustomPerspective.$(H): SmallSense__CustomPerspective.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoryBuilder.$(O) SmallSense__CustomRefactoryBuilder.$(H): SmallSense__CustomRefactoryBuilder.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeFormatter.$(O) SmallSense__CustomSourceCodeFormatter.$(H): SmallSense__CustomSourceCodeFormatter.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeGenerator.$(O) SmallSense__CustomSourceCodeGenerator.$(H): SmallSense__CustomSourceCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/parser/RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/CodeGenerator.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeSelection.$(O) SmallSense__CustomSourceCodeSelection.$(H): SmallSense__CustomSourceCodeSelection.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseHelper.$(O) SmallSense__CustomTestCaseHelper.$(H): SmallSense__CustomTestCaseHelper.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)stx_goodies_smallsense_refactoring_custom.$(O) stx_goodies_smallsense_refactoring_custom.$(H): stx_goodies_smallsense_refactoring_custom.st $(INCLUDE_TOP)/stx/libbasic/LibraryDefinition.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserChangeManager.$(O) SmallSense__CustomBrowserChangeManager.$(H): SmallSense__CustomBrowserChangeManager.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserContext.$(O) SmallSense__CustomBrowserContext.$(H): SmallSense__CustomBrowserContext.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomContext.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGenerator.$(O) SmallSense__CustomCodeGenerator.$(H): SmallSense__CustomCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLocalChangeManager.$(O) SmallSense__CustomLocalChangeManager.$(H): SmallSense__CustomLocalChangeManager.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNoneSourceCodeFormatter.$(O) SmallSense__CustomNoneSourceCodeFormatter.$(H): SmallSense__CustomNoneSourceCodeFormatter.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRBLocalSourceCodeFormatter.$(O) SmallSense__CustomRBLocalSourceCodeFormatter.$(H): SmallSense__CustomRBLocalSourceCodeFormatter.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoring.$(O) SmallSense__CustomRefactoring.$(H): SmallSense__CustomRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSilentDialog.$(O) SmallSense__CustomSilentDialog.$(H): SmallSense__CustomSilentDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubContext.$(O) SmallSense__CustomSubContext.$(H): SmallSense__CustomSubContext.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomContext.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUserDialog.$(O) SmallSense__CustomUserDialog.$(H): SmallSense__CustomUserDialog.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomAccessMethodsCodeGenerator.$(O) SmallSense__CustomAccessMethodsCodeGenerator.$(H): SmallSense__CustomAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionRefactoring.$(O) SmallSense__CustomCodeSelectionRefactoring.$(H): SmallSense__CustomCodeSelectionRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomInspectorTabCodeGenerator.$(O) SmallSense__CustomInspectorTabCodeGenerator.$(H): SmallSense__CustomInspectorTabCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomIsAbstractCodeGenerator.$(O) SmallSense__CustomIsAbstractCodeGenerator.$(H): SmallSense__CustomIsAbstractCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNewClassGenerator.$(O) SmallSense__CustomNewClassGenerator.$(H): SmallSense__CustomNewClassGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(O) SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(H): SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubclassResponsibilityCodeGenerator.$(O) SmallSense__CustomSubclassResponsibilityCodeGenerator.$(H): SmallSense__CustomSubclassResponsibilityCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseCodeGenerator.$(O) SmallSense__CustomTestCaseCodeGenerator.$(H): SmallSense__CustomTestCaseCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseMethodCodeGenerator.$(O) SmallSense__CustomTestCaseMethodCodeGenerator.$(H): SmallSense__CustomTestCaseMethodCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseSetUpCodeGenerator.$(O) SmallSense__CustomTestCaseSetUpCodeGenerator.$(H): SmallSense__CustomTestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseTearDownCodeGenerator.$(O) SmallSense__CustomTestCaseTearDownCodeGenerator.$(H): SmallSense__CustomTestCaseTearDownCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(O) SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(H): SmallSense__CustomUpdateTestCaseCategoryRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGenerator.$(O) SmallSense__CustomVisitorCodeGenerator.$(H): SmallSense__CustomVisitorCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorClassGenerator.$(O) SmallSense__CustomCodeGeneratorClassGenerator.$(H): SmallSense__CustomCodeGeneratorClassGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(O) SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(H): SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionToResourceTranslation.$(O) SmallSense__CustomCodeSelectionToResourceTranslation.$(H): SmallSense__CustomCodeSelectionToResourceTranslation.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(O) SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(H): SmallSense__CustomDefaultGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMultiSetterMethodsCodeGenerator.$(O) SmallSense__CustomMultiSetterMethodsCodeGenerator.$(H): SmallSense__CustomMultiSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPrintCodeSelectionRefactoring.$(O) SmallSense__CustomPrintCodeSelectionRefactoring.$(H): SmallSense__CustomPrintCodeSelectionRefactoring.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoringClassGenerator.$(O) SmallSense__CustomRefactoringClassGenerator.$(H): SmallSense__CustomRefactoringClassGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(O) SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(H): SmallSense__CustomSimpleAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseCodeGenerator.$(O) SmallSense__CustomUITestCaseCodeGenerator.$(H): SmallSense__CustomUITestCaseCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseSetUpCodeGenerator.$(O) SmallSense__CustomUITestCaseSetUpCodeGenerator.$(H): SmallSense__CustomUITestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomTestCaseSetUpCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(O) SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(H): SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomVisitorCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)/stx/goodies/smallsense/refactoring_custom/SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/AddClassChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/AddMethodChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/RefactoryChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/changes/RefactoryClassChange.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBAbstractClass.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBClass.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBMetaclass.$(H) $(INCLUDE_TOP)/stx/goodies/refactoryBrowser/helpers/RBMethod.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libtool/SystemBrowser.$(H) $(INCLUDE_TOP)/stx/libtool/Tools__NewSystemBrowser.$(H) $(INCLUDE_TOP)/stx/libview2/ApplicationModel.$(H) $(INCLUDE_TOP)/stx/libview2/Model.$(H) $(STCHDR)
+
+# ENDMAKEDEPEND --- do not remove this line
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/Make.spec	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,190 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+#
+# 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/refactoring_custom
+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::CustomChangeManager \
+	SmallSense::CustomClassQuery \
+	SmallSense::CustomCodeGeneratorOrRefactoring \
+	SmallSense::CustomContext \
+	SmallSense::CustomDialog \
+	SmallSense::CustomManager \
+	SmallSense::CustomMenuBuilder \
+	SmallSense::CustomMock \
+	SmallSense::CustomNamespace \
+	SmallSense::CustomParseTreeRewriter \
+	SmallSense::CustomPerspective \
+	SmallSense::CustomRefactoryBuilder \
+	SmallSense::CustomSourceCodeFormatter \
+	SmallSense::CustomSourceCodeGenerator \
+	SmallSense::CustomSourceCodeSelection \
+	SmallSense::CustomTestCaseHelper \
+	stx_goodies_smallsense_refactoring_custom \
+	SmallSense::CustomBrowserChangeManager \
+	SmallSense::CustomBrowserContext \
+	SmallSense::CustomCodeGenerator \
+	SmallSense::CustomLocalChangeManager \
+	SmallSense::CustomNoneSourceCodeFormatter \
+	SmallSense::CustomRBLocalSourceCodeFormatter \
+	SmallSense::CustomRefactoring \
+	SmallSense::CustomSilentDialog \
+	SmallSense::CustomSubContext \
+	SmallSense::CustomUserDialog \
+	SmallSense::CustomAccessMethodsCodeGenerator \
+	SmallSense::CustomCodeSelectionRefactoring \
+	SmallSense::CustomInspectorTabCodeGenerator \
+	SmallSense::CustomIsAbstractCodeGenerator \
+	SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator \
+	SmallSense::CustomNewClassGenerator \
+	SmallSense::CustomReplaceIfNilWithIfTrueRefactoring \
+	SmallSense::CustomSubclassResponsibilityCodeGenerator \
+	SmallSense::CustomTestCaseCodeGenerator \
+	SmallSense::CustomTestCaseMethodCodeGenerator \
+	SmallSense::CustomTestCaseSetUpCodeGenerator \
+	SmallSense::CustomTestCaseTearDownCodeGenerator \
+	SmallSense::CustomUpdateTestCaseCategoryRefactoring \
+	SmallSense::CustomVisitorCodeGenerator \
+	SmallSense::CustomChangeNotificationAccessMethodsCodeGenerator \
+	SmallSense::CustomChangeNotificationSetterMethodsCodeGenerator \
+	SmallSense::CustomCodeGeneratorClassGenerator \
+	SmallSense::CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator \
+	SmallSense::CustomCodeSelectionToResourceTranslation \
+	SmallSense::CustomDefaultGetterMethodsCodeGenerator \
+	SmallSense::CustomLazyInitializationAccessMethodsCodeGenerator \
+	SmallSense::CustomLazyInitializationGetterMethodsCodeGenerator \
+	SmallSense::CustomMultiSetterMethodsCodeGenerator \
+	SmallSense::CustomPrintCodeSelectionRefactoring \
+	SmallSense::CustomRefactoringClassGenerator \
+	SmallSense::CustomSimpleAccessMethodsCodeGenerator \
+	SmallSense::CustomSimpleGetterMethodsCodeGenerator \
+	SmallSense::CustomSimpleSetterMethodsCodeGenerator \
+	SmallSense::CustomUITestCaseCodeGenerator \
+	SmallSense::CustomUITestCaseSetUpCodeGenerator \
+	SmallSense::CustomValueHolderAccessMethodsCodeGenerator \
+	SmallSense::CustomValueHolderGetterMethodsCodeGenerator \
+	SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator \
+	SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator \
+	SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator \
+	SmallSense::CustomVisitorCodeGeneratorAcceptVisitor \
+	SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGenerator \
+
+
+
+
+COMMON_OBJS= \
+    $(OUTDIR_SLASH)SmallSense__CustomChangeManager.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomClassQuery.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomCodeGeneratorOrRefactoring.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomContext.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomManager.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomMenuBuilder.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomMock.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomNamespace.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomParseTreeRewriter.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomPerspective.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomRefactoryBuilder.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSourceCodeFormatter.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSourceCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSourceCodeSelection.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomTestCaseHelper.$(O) \
+    $(OUTDIR_SLASH)stx_goodies_smallsense_refactoring_custom.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomBrowserChangeManager.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomBrowserContext.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomLocalChangeManager.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomNoneSourceCodeFormatter.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomRBLocalSourceCodeFormatter.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomRefactoring.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSilentDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSubContext.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomUserDialog.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomAccessMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomCodeSelectionRefactoring.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomInspectorTabCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomIsAbstractCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomNewClassGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSubclassResponsibilityCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomTestCaseCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomTestCaseMethodCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomTestCaseSetUpCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomTestCaseTearDownCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomVisitorCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomCodeGeneratorClassGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomCodeSelectionToResourceTranslation.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomMultiSetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomPrintCodeSelectionRefactoring.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomRefactoringClassGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomUITestCaseCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomUITestCaseSetUpCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(O) \
+    $(OUTDIR_SLASH)SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(O) \
+    $(OUTDIR_SLASH)extensions.$(O) \
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/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/refactoring_custom/README.md	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,7 @@
+# API for Code Generation and Refactoring #
+
+This repository contains bachelor's thesis source codes for Czech Technical University in Prague - Faculty of Information Technology - Department of Software Engineering. Submitted version is marked with tag #thesis_submission. Further reading can be found in folder docs or thesis text repo https://bitbucket.org/jnesveda/refactoring_custom_thesis .
+
+### Overview from docs ###
+
+API for programmers who would like to create their own code generators or refactorings in Smalltalk/X environment. This API is intended to be more user-friendly than existing possibilities in STX version 6.2.5 . The documentation here is not very detailed and further reading can be found in bachelor's thesis text (BP_Nesveda_Jakub_2015.pdf), especially chapter "API in a nutshell" describes how to write code generators or refactoring.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAccessMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,223 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomAccessMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #(Accessors)
+
+    "Created: / 22-08-2014 / 18:45:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+
+    ^ aCustomContext selectedClasses notEmptyOrNil
+
+    "Modified: / 11-05-2014 / 17:37:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+
+    ^ aCustomPerspective isClassPerspective or: [
+        aCustomPerspective isInstanceVariablePerspective
+    ]
+
+    "Modified: / 11-05-2014 / 16:44:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CustomAccessMethodsCodeGenerator
+
+    "Modified: / 01-07-2014 / 16:19:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'accessing'!
+
+protocol
+    "Returns protocol name in which will belong getter method"
+
+    ^ 'accessing'
+
+    "Created: / 12-05-2014 / 23:26:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Should return getter method source code for given class and variable name"
+
+    self subclassResponsibility
+
+    "Created: / 12-05-2014 / 22:44:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-05-2014 / 20:33:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    | selectedVariables |
+
+    selectedVariables := aCustomContext selectedVariables.
+
+    aCustomContext selectedClasses do: [ :class | 
+        | variableNames |    
+
+        variableNames := class instVarNames.
+
+        selectedVariables notEmptyOrNil ifTrue: [
+            variableNames := variableNames select: [ :variableName | 
+                selectedVariables includes: variableName
+            ]
+        ].
+
+        variableNames do:[ :variableName |
+            | source |
+
+            source := self sourceForClass: class variableName: variableName.
+
+            model
+                compile: source 
+                in: (self methodClass: class) 
+                classified: self protocol
+        ]
+    ]
+
+    "Modified: / 25-01-2015 / 14:39:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator methodsFor:'protected'!
+
+argNameForMethodName: aMethodName
+    "Returns argument name based on given method name"
+
+    ((aMethodName size > 2) and:[ (aMethodName startsWith:'is') and:[ (aMethodName at:3) isUppercase ]])
+    ifTrue:[
+        ^ 'aBoolean'
+    ].
+
+    ^ 'something'
+
+    "Created: / 04-07-2014 / 10:24:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+defaultMethodNameFor: aVarName
+    "Creates getter method name for retrieving default variable value"
+
+    ^ 'default', aVarName asUppercaseFirst
+
+    "Created: / 29-06-2014 / 23:26:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodClass: aClass
+    "Returns class for which will be generated a getter method.
+    By overriding this is possible for example to specify only metaclass of given class."
+
+    ^ aClass
+
+    "Created: / 29-06-2014 / 22:52:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodNameFor: aVarName
+    "Creates getter method name for given variable name"
+
+    | methodName |
+
+    methodName := aVarName.
+    aVarName isUppercaseFirst ifTrue:[
+        (aVarName conform:[:ch | ch isLetter not or:[ch isUppercase]]) ifFalse:[      "/ allow all-uppercase for class-vars
+            methodName := methodName asLowercaseFirst. 
+        ]
+    ].
+
+    ^ methodName
+
+    "Created: / 12-05-2014 / 22:04:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+varTypeOf: aVarName class: aClass
+    "Returns variable type as string for given variable name and class"
+
+    | classesClassVars varType |
+
+    classesClassVars := aClass theNonMetaclass allClassVarNames.
+
+    varType := (classesClassVars includes: aVarName) 
+        ifTrue:['static'] 
+        ifFalse:[
+            (aClass isMeta ifTrue:['classInstVar'] ifFalse:['instance'])].
+
+    ^ varType
+
+    "Created: / 12-05-2014 / 21:40:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 20-06-2014 / 21:30:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAccessMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,272 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomAccessMethodsCodeGeneratorTests
+	instanceVariableNames:'expectedSource class'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    | mockClass mockClassInstance |
+
+    mockClass := mock mockClassOf:CustomAccessMethodsCodeGenerator.
+    mockClass compileMockMethod: 'description ^ ''some description'' '.
+
+    mockClassInstance := mockClass new.
+    mockClassInstance compileMockMethod: 'sourceForClass:aClass variableName:varName
+        ^ varName, '' ^ '', varName'.
+
+    ^ mockClassInstance
+
+    "Modified: / 26-09-2014 / 10:54:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_arg_name_for_method_name_boolean
+    | actualArgName |
+
+    actualArgName := generatorOrRefactoring argNameForMethodName: 'isSomething'.
+
+    self assert: 'aBoolean' = actualArgName
+
+    "Created: / 04-07-2014 / 12:38:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_arg_name_for_method_name_other
+    | actualArgName |
+
+    actualArgName := generatorOrRefactoring argNameForMethodName: 'selector'.
+
+    self assert: 'something' = actualArgName
+
+    "Created: / 04-07-2014 / 12:39:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_in_context_with_none_selected_variable
+    | classWithInstVars testCompleted |
+
+    testCompleted := false.
+    [ 
+        classWithInstVars := self createClass.
+        classWithInstVars
+            instanceVariableNames: #('instanceVariable_01' 'instanceVariable_02' 'instanceVariable_03');
+            compile.
+
+        context selectedClasses: (Array with: classWithInstVars).
+
+        generatorOrRefactoring executeInContext: context.
+
+        self assertMethodCount: 3 inClass: classWithInstVars.
+
+        expectedSource := 'instanceVariable_02 ^ instanceVariable_02'.
+        self assertMethodSource: expectedSource atSelector: #instanceVariable_02.
+
+        expectedSource := 'instanceVariable_01 ^ instanceVariable_01'.
+        self assertMethodSource: expectedSource atSelector: #instanceVariable_01.
+
+        expectedSource := 'instanceVariable_03 ^ instanceVariable_03'.
+        self assertMethodSource: expectedSource atSelector: #instanceVariable_03.
+
+        testCompleted := true.
+    ] ensure: [
+        self assert: testCompleted
+    ].
+
+    "Created: / 20-06-2014 / 20:29:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-11-2014 / 15:44:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_in_context_with_one_selected_variable
+    | class |
+
+    class := self createClass.
+    class
+        instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02' with: 'instanceVariable_03');
+        compile.
+
+    context selectedClasses: (Array with: class).
+    context selectedVariables: (Array with: 'instanceVariable_02').
+
+    generatorOrRefactoring executeInContext: context.
+
+    self assertMethodCount: 1 inClass: class.
+
+    expectedSource := 'instanceVariable_02 ^ instanceVariable_02'.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable_02.
+
+    "Created: / 17-06-2014 / 08:57:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-09-2014 / 10:57:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_in_context_with_two_selected_variables
+    | class |
+
+    class := self createClass.
+    class
+        instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02' with: 'instanceVariable_03');
+        compile.
+
+    context selectedClasses: (Array with: class).
+    context selectedVariables: (Array with: 'instanceVariable_02' with: 'instanceVariable_01').
+
+    generatorOrRefactoring executeInContext: context.
+
+    self assertMethodCount: 2 inClass: class.
+
+    expectedSource := 'instanceVariable_02 ^ instanceVariable_02'.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable_02.
+
+    expectedSource := 'instanceVariable_01 ^ instanceVariable_01'.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable_01.
+
+    "Created: / 20-06-2014 / 20:26:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-09-2014 / 11:03:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_default_method_name_for_variable_name
+    | actualDefaultMethodName |
+
+    actualDefaultMethodName := generatorOrRefactoring defaultMethodNameFor: 'varName'.
+
+    self assert: 'defaultVarName' = actualDefaultMethodName
+
+    "Created: / 29-06-2014 / 23:33:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_all_upper_case
+    | actualMethodName |
+
+    actualMethodName := generatorOrRefactoring methodNameFor: 'VAR'.
+
+    self assert: 'VAR' = actualMethodName
+
+    "Created: / 20-06-2014 / 21:11:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_class_variable
+    | actualMethodName |
+
+    actualMethodName := generatorOrRefactoring methodNameFor: 'ClassVar'.
+
+    self assert: 'classVar' = actualMethodName
+
+    "Created: / 20-06-2014 / 20:36:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_instance_variable
+
+    self assert: 'instVar' = (generatorOrRefactoring methodNameFor: 'instVar')
+
+    "Created: / 20-06-2014 / 20:35:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_name_for_number
+    | actualMethodName |
+
+    actualMethodName := generatorOrRefactoring methodNameFor: 'Var_7'.
+
+    self assert: 'var_7' = actualMethodName
+
+    "Created: / 20-06-2014 / 21:13:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_var_type_of_class_instance_variable
+    | actualVarType |
+
+    class := self createClass theMetaclass.
+    class
+        instanceVariableNames: (Array with: 'ClassInstVar1' with: 'ClassInstVar2').
+
+    self assert: class isMeta.
+
+    actualVarType := generatorOrRefactoring varTypeOf: 'ClassInstVar2' class: class.
+
+    self assert: 'classInstVar' = actualVarType
+
+    "Created: / 23-06-2014 / 19:27:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-09-2014 / 21:33:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_var_type_of_instance_variable
+    | actualVarType |
+
+    class := self createClass.
+    class instanceVariableNames: 'instVar1 instVar2'.
+
+    actualVarType := generatorOrRefactoring varTypeOf: 'instVar2' class: class.
+
+    self assert: 'instance' = actualVarType
+
+    "Created: / 23-06-2014 / 19:26:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_var_type_of_static
+    | actualVarType |
+
+    class := self createClass.
+    class classVariableNames: (Array with: 'ClassVar1' with: 'ClassVar2').
+
+    actualVarType := generatorOrRefactoring varTypeOf: 'ClassVar2' class: class.
+
+    self assert: 'static' = actualVarType
+
+    "Created: / 20-06-2014 / 21:22:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-09-2014 / 21:47:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAddClassChangeTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,379 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomAddClassChangeTests
+	instanceVariableNames:'className change'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomAddClassChangeTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomAddClassChangeTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+    ^ nil
+
+    "Created: / 16-10-2014 / 22:57:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddClassChangeTests methodsFor:'initialize & release'!
+
+setUp
+    super setUp.
+
+    className := 'DummyTestClass01'.
+    self assert: (Smalltalk classNamed: className) isNil.    
+
+    change := AddClassChange definition: '
+    Object subclass:#', className, '
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:''''
+    '.
+
+    "Modified: / 16-10-2014 / 22:55:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+    | realClass |
+    
+    realClass := Smalltalk classNamed: className.
+    realClass notNil ifTrue: [
+        realClass removeFromSystem
+    ].
+
+    super tearDown.
+
+    "Modified: / 30-11-2014 / 17:04:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddClassChangeTests methodsFor:'tests'!
+
+test_argumens_by_selector_parts_from_message_arguments_missing
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+    messageNode arguments: #().
+
+    expectedResult := Dictionary new.
+    actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:12:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_none_argument
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'Object name'.
+
+    expectedResult := Dictionary new.
+    actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:03:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_one_argument
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'Object subclass: SomeClass01'.
+
+    expectedResult := Dictionary new
+        at: #subclass: put: (messageNode arguments first);
+        yourself.
+
+    actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:05:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:55:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_selector_empty
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+    messageNode selectorParts: #().
+
+    expectedResult := Dictionary new
+        at: 1 put: (messageNode arguments first);
+        at: 2 put: (messageNode arguments second);
+        yourself.
+
+    actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:10:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:55:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_selector_missing
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+    messageNode selectorParts: nil.
+
+    expectedResult := Dictionary new
+        at: 1 put: (messageNode arguments first);
+        at: 2 put: (messageNode arguments second);
+        yourself.
+
+    actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:10:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:55:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_argumens_by_selector_parts_from_message_two_arguments
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+
+    expectedResult := Dictionary new
+        at: #subclass: put: (messageNode arguments first);
+        at: #category: put: (messageNode arguments second);
+        yourself.
+
+    actualResult := change argumensBySelectorPartsFromMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:09:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:55:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_fill_out_definition_ordinary_class
+
+    change definition: 'SomeObject01 subclass:#DummySubclass01
+        instanceVariableNames:''inst01 inst02''
+        classVariableNames:''Cls01 Cls02''
+        poolDictionaries:''pool01''
+        category:''Some-Category01'''.
+
+    change fillOutDefinition. 
+
+    self assert: #DummySubclass01 = (change changeClassName).
+    self assert: change privateInClassName isNil.
+    self assert: #SomeObject01 = (change superclassName).
+    self assert: #'Some-Category01' = (change category).
+    self assert: (#(inst01 inst02) asStringCollection) = (change instanceVariableNames).
+    self assert: (#(Cls01 Cls02) asStringCollection) = (change classVariableNames).
+    self assert: (#(pool01) asOrderedCollection) = (change poolDictionaryNames).
+
+    "Created: / 16-11-2014 / 16:12:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 12:40:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_fill_out_definition_private_class_01
+
+    change definition: 'Object subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:Object'.
+
+    change fillOutDefinition. 
+
+    self assert: #'Object::DummyPrivateClass01' = (change changeClassName).
+    self assert: #Object = (change privateInClassName).
+    self assert: #Object = (change superclassName).
+    self assert: #'' = (change category).
+    self assert: (StringCollection new) = (change instanceVariableNames).
+    self assert: (StringCollection new) = (change classVariableNames).
+    self assert: (OrderedCollection new) = (change poolDictionaryNames).
+
+    "Created: / 16-11-2014 / 15:56:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:08:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_fill_out_definition_private_class_02
+
+    change definition: 'SomeObject01 subclass:#DummyPrivateClass01
+        instanceVariableNames:''inst01 inst02''
+        classVariableNames:''Cls01 Cls02''
+        poolDictionaries:''pool01''
+        privateIn:SomeObject02'.
+
+    change fillOutDefinition. 
+
+    self assert: #'SomeObject02::DummyPrivateClass01' = (change changeClassName).
+    self assert: #SomeObject02 = (change privateInClassName).
+    self assert: #SomeObject01 = (change superclassName).
+    self assert: #'' = (change category).
+    self assert: (#(inst01 inst02) asStringCollection) = (change instanceVariableNames).
+    self assert: (#(Cls01 Cls02) asStringCollection) = (change classVariableNames).
+    self assert: (#(pool01) asOrderedCollection) = (change poolDictionaryNames).
+
+    "Created: / 16-11-2014 / 16:08:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:08:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_get_and_set_package
+
+    self assert: change package isNil.
+
+    change package: #some_package01.
+
+    self assert: #some_package01 = (change package).
+
+    "Created: / 17-10-2014 / 09:06:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_message_name
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'Object subclass: SomeClass01 category: #SomeCategory01 '.
+
+    expectedResult := false.
+    actualResult := change isValidMessageName: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:15:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_message_name_with_private_class
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'DummyObject01 subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyObject02'.
+
+    expectedResult := true.
+    actualResult := change isValidMessageName: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:16:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_subclass_creation_message_for_private_class
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'DummyObject01 subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyObject02'.
+
+    expectedResult := true.
+    actualResult := change isValidSubclassCreationMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:23:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_subclass_creation_message_for_private_class_wrong
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'DummyObject01 subclass:DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyObject02'.
+
+    expectedResult := false.
+    actualResult := change isValidSubclassCreationMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:33:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_valid_subclass_creation_message_for_unkown_message
+    | expectedResult actualResult messageNode |
+
+    messageNode := RBParser parseExpression: 'DummyObject01 subclass:#DummyPrivateClass01'.
+
+    expectedResult := false.
+    actualResult := change isValidSubclassCreationMessage: messageNode.
+
+    self assert: expectedResult = actualResult
+
+    "Created: / 16-11-2014 / 15:34:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_primitive_execute_with_package
+
+    | class |
+
+    change package: #some_package01.
+    change primitiveExecute.
+
+    self assertClassExists: className.
+    class := Smalltalk classNamed: className.
+    self assert: #some_package01 = (class package).
+
+    "Created: / 16-10-2014 / 22:49:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 17-10-2014 / 08:10:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_primitive_execute_without_package
+
+    | class |
+
+    change primitiveExecute.
+
+    self assertClassExists: className.
+    class := Smalltalk classNamed: className.
+    self assert: (PackageId noProjectID) = (class package).
+
+    "Created: / 17-10-2014 / 08:11:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomAddMethodChangeTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,254 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomAddMethodChangeTests
+	instanceVariableNames:'class change'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomAddMethodChangeTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomAddMethodChangeTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+    ^ nil
+
+    "Created: / 16-10-2014 / 22:57:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddMethodChangeTests methodsFor:'initialize & release'!
+
+setUp
+    super setUp.
+
+    class := model createClassImmediate: 'DummyTestClass01'.  
+    change := AddMethodChange compile: 'selector_01 ^ 1' in: class.
+
+    "Modified: / 17-10-2014 / 09:31:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddMethodChangeTests methodsFor:'tests'!
+
+test_as_undo_operation_new_package_nil
+
+    | undo |
+
+    model createMethodImmediate: class 
+        protocol: 'a protocol' 
+        source: 'selector_01 ^ 555' 
+        package: #some_package01.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+    change package: nil.
+    undo := change execute. "calls internally asUndoOperation"
+
+    self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    undo execute.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    "Created: / 17-10-2014 / 10:39:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_new_package_not_set
+
+    | undo |
+
+    model createMethodImmediate: class 
+        protocol: 'a protocol' 
+        source: 'selector_01 ^ 555' 
+        package: #some_package01.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+    undo := change execute. "calls internally asUndoOperation"
+
+    self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    undo execute.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    "Created: / 17-10-2014 / 10:43:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_different_from_new_package
+
+    | undo |
+
+    model createMethodImmediate: class 
+        protocol: 'a protocol' 
+        source: 'selector_01 ^ 555' 
+        package: #some_package02.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+    change package: #some_package01.
+    undo := change execute. "calls internally asUndoOperation"
+
+    self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    undo execute.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+    self assert: #some_package02 = ((class compiledMethodAt: #selector_01) package).
+
+    "Created: / 17-10-2014 / 10:38:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_nil
+
+    | undo |
+
+    model createMethodImmediate: class 
+        protocol: 'a protocol' 
+        source: 'selector_01 ^ 555' 
+        package: nil.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+    change package: #some_package01.
+    undo := change execute. "calls internally asUndoOperation"
+
+    self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    undo execute.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+    self assert: (PackageId noProjectID) = ((class compiledMethodAt: #selector_01) package).
+
+    "Created: / 17-10-2014 / 10:37:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_same_as_new
+
+    | undo |
+
+    model createMethodImmediate: class 
+        protocol: 'a protocol' 
+        source: 'selector_01 ^ 555' 
+        package: #some_package01.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+    change package: #some_package01.
+    undo := change execute. "calls internally asUndoOperation"
+
+    self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    undo execute.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    "Created: / 17-10-2014 / 10:08:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_undo_operation_old_package_same_as_new_with_redo
+
+    | undo redo |
+
+    model createMethodImmediate: class 
+        protocol: 'a protocol' 
+        source: 'selector_01 ^ 555' 
+        package: #some_package01.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+
+    change package: #some_package01.
+    undo := change execute. "calls internally asUndoOperation"
+
+    self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    redo := undo execute.
+
+    self assertMethodSource: 'selector_01 ^ 555' atSelector: #selector_01 forClass: class.
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    redo execute.
+
+    self assertMethodSource: 'selector_01 ^ 1' atSelector: #selector_01 forClass: class.
+    self assert: #some_package01 = ((class compiledMethodAt: #selector_01) package).
+
+    "Created: / 17-10-2014 / 22:14:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_get_and_set_package
+
+    self assert: change package isNil.
+
+    change package: #some_package01.
+
+    self assert: #some_package01 = (change package).
+
+    "Created: / 17-10-2014 / 09:35:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomAddMethodChangeTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserChangeManager.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,74 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomChangeManager subclass:#CustomBrowserChangeManager
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomBrowserChangeManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Implementation of global Browser refactory changes 
+    - so you could see them for example in Browser - Operations menu.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>  
+
+"
+! !
+
+!CustomBrowserChangeManager methodsFor:'performing-changes'!
+
+performChange: aRefactoringChange
+
+    RefactoryChangeManager instance performChange: aRefactoringChange
+
+    "Created: / 31-05-2014 / 13:20:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserContext.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,182 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomContext subclass:#CustomBrowserContext
+	instanceVariableNames:'state'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomBrowserContext class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomBrowserContext class methodsFor:'instance creation'!
+
+perspective: perspective state: state
+    ^ self new perspective: perspective state: state
+
+    "Created: / 26-01-2014 / 11:00:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext methodsFor:'accessing'!
+
+perspective:perspectiveArg state:stateArg 
+    perspective := perspectiveArg.
+    state := stateArg.
+
+    "Created: / 26-01-2014 / 11:00:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext methodsFor:'accessing-selection'!
+
+selectedClassCategories
+
+    ^ state selectedCategories value
+
+    "Modified: / 05-08-2014 / 21:35:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses
+    "Returns a set of classes currently selected in
+     the browser"
+
+    ^ state selectedClasses value ? #() collect:[ :cls | self asRBClass: cls ]
+
+    "Created: / 26-01-2014 / 22:06:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-11-2014 / 20:08:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-12-2014 / 09:43:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes
+    | codeSelection currentMethod codeView |
+
+    currentMethod := state theSingleSelectedMethod.
+    codeView := state codeView.
+
+    (codeView isNil or: [ currentMethod isNil ]) ifTrue: [ 
+        ^ nil
+    ].
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        selectedInterval: codeView selectedInterval;
+        currentSourceCode: codeView contentsAsString; 
+        selectedMethod: currentMethod; 
+        selectedClass: currentMethod mclass;
+        selectedSelector: currentMethod selector.
+        
+
+    ^ Array with: codeSelection
+
+    "Created: / 18-08-2014 / 21:34:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 18-08-2014 / 23:51:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods
+
+    ^ state selectedMethods value ? #() collect:[ :m | self asRBMethod: m ]
+
+    "Modified: / 14-11-2014 / 20:17:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 29-12-2014 / 10:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages
+
+    ^ state packageFilter value
+
+    "Modified: / 05-08-2014 / 21:38:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols
+    "Returns a collection of method protocols which are visible and selected in the Browser."
+    
+    |protocols allIncluded|
+
+    protocols := state selectedProtocols value.
+     "Support to return all protocols when all protocol ('* all *') is selected in the Browser.
+     This is a little duplicate as in Tools::NewSystemBowser >> selectedProtocolsDo: ,
+     but using this method would require a referece to the Browser and furthermore is marked as private."
+    allIncluded := protocols ? #() 
+            includes:(Tools::BrowserList nameListEntryForALL).
+    allIncluded ifTrue:[
+        protocols := Set new.
+        self selectedClasses do:[:class | 
+            protocols addAll:class categories
+        ]
+    ].
+    ^ protocols
+
+    "Modified: / 19-11-2014 / 08:45:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables
+
+    ^ state variableFilter value
+
+    "Modified: / 17-05-2014 / 13:29:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext methodsFor:'testing'!
+
+isInteractiveContext
+    "Return true, if this generator/refactoring context is interactive,
+     i.e., if it may interact with user (like asking for class name or
+     similar) or not. 
+
+     Generally speaking, only top-level context is interactive an only
+     if generator/refactoring was triggerred from menu.
+    "
+    ^ true
+
+    "Created: / 16-09-2014 / 09:23:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomBrowserContext class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserContextTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,168 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomBrowserContextTests
+	instanceVariableNames:'state'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomBrowserContextTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomBrowserContextTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+    ^ nil
+
+    "Created: / 28-10-2014 / 19:17:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserContextTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    state := Tools::NavigationState new.
+    context := CustomBrowserContext perspective: CustomPerspective new state: state
+
+    "Modified: / 25-01-2015 / 16:08:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserContextTests methodsFor:'tests'!
+
+test_selected_classes_empty
+
+    self assert: state selectedClasses value isNil.
+    self assert: (context selectedClasses) = #()
+
+    "Modified: / 29-12-2014 / 10:17:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_all
+    | expectedProtocols actualProtocols class |
+
+    class := model createClassImmediate: #DummyClassForTestsCase01.
+    model createMethodImmediate: class protocol: 'protocol_01' source: 'sel_01 ^ 1'.
+    model createMethodImmediate: class protocol: 'protocol_02' source: 'sel_02 ^ 2'.
+
+    expectedProtocols := Set new 
+        add: #protocol_01;
+        add: #protocol_02;
+        yourself.
+
+    state selectedProtocols setValue: (Array with: 'protocol_01' with: (Tools::BrowserList nameListEntryForALL)).
+    state selectedClasses setValue: (Array with: class).
+
+    actualProtocols := context selectedProtocols.    
+    
+    self assert: expectedProtocols = actualProtocols.
+
+    "Created: / 28-10-2014 / 19:21:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_all_two_classes
+    | expectedProtocols actualProtocols class01 class02 |
+
+    class01 := model createClassImmediate: #DummyClassForTestsCase01.
+    model createMethodImmediate: class01 protocol: 'protocol_01' source: 'sel_01 ^ 1'.
+    model createMethodImmediate: class01 protocol: 'protocol_02' source: 'sel_02 ^ 2'.
+
+    class02 := model createClassImmediate: #DummyClassForTestsCase02.
+    model createMethodImmediate: class02 protocol: 'protocol_01' source: 'sel_09 ^ 9'.
+    model createMethodImmediate: class02 protocol: 'protocol_03' source: 'sel_03 ^ 3'.
+
+    expectedProtocols := Set new 
+        add: #protocol_01;
+        add: #protocol_02;
+        add: #protocol_03;
+        yourself.
+
+    state selectedProtocols setValue: (Array with: 'protocol_01' with: (Tools::BrowserList nameListEntryForALL)).
+    state selectedClasses setValue: (Array with: class01 with: class02).
+
+    actualProtocols := context selectedProtocols.    
+
+    self assert: expectedProtocols = actualProtocols.
+
+    "Created: / 28-10-2014 / 19:26:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-11-2014 / 09:33:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_empty
+    | expectedProtocols actualProtocols |
+
+    expectedProtocols := nil.
+    state selectedProtocols setValue: nil.
+
+    actualProtocols := context selectedProtocols.    
+    
+    self assert: expectedProtocols = actualProtocols.
+
+    "Created: / 05-11-2014 / 18:55:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_method_protocols_subset
+    | expectedProtocols actualProtocols |
+
+    expectedProtocols := Array with: 'protocol_01' with: 'protocol_02'.
+    state selectedProtocols setValue: expectedProtocols.
+
+    actualProtocols := context selectedProtocols.    
+    
+    self assert: expectedProtocols = actualProtocols.
+
+    "Modified: / 28-10-2014 / 19:17:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_methods_empty
+    
+    self assert: state selectedMethods value isNil.
+    self assert: (context selectedMethods) = #()
+
+    "Modified: / 29-12-2014 / 10:20:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomBrowserEnvironmentTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,93 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomBrowserEnvironmentTests
+	instanceVariableNames:'environment'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomBrowserEnvironmentTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomBrowserEnvironmentTests methodsFor:'initialization & release'!
+
+setUp
+
+    environment := BrowserEnvironment new.
+
+    "Modified: / 05-11-2014 / 21:29:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomBrowserEnvironmentTests methodsFor:'tests'!
+
+test_which_category_includes_existing_class
+    | expectedCategory actualCategory className |
+
+    expectedCategory := self class category.
+
+    className := self class name.
+    actualCategory := environment whichCategoryIncludes: className.
+
+    self assert: expectedCategory = actualCategory.
+
+    "Created: / 05-11-2014 / 21:33:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_which_category_includes_non_existing_class
+    | expectedCategory actualCategory className |
+
+    expectedCategory := nil.
+
+    className := #DummyClassForTestCase01.
+    self assert: (Smalltalk at: className) isNil.
+
+    actualCategory := environment whichCategoryIncludes: className.
+
+    self assert: expectedCategory = actualCategory.
+
+    "Created: / 05-11-2014 / 21:32:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeManager.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomChangeManager
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomChangeManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Interface for operations with refactory browser changes needed for CustomCodeGenerator.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomChangeManager class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CustomChangeManager
+! !
+
+!CustomChangeManager methodsFor:'performing-changes'!
+
+performChange: aRefactoringChange
+
+    self subclassResponsibility
+
+    "Created: / 31-05-2014 / 13:02:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeManager class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomChangeNotificationAccessMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomChangeNotificationAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Access Method(s) with Change Notification for selected instance variables'
+
+    "Modified: / 13-07-2014 / 16:39:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Access Method(s) with Change Notification'
+
+    "Modified: / 13-07-2014 / 16:39:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Creates access methods with change notification in setter for given context"
+
+    self executeSubGeneratorOrRefactoringClasses:(Array 
+                  with:CustomSimpleGetterMethodsCodeGenerator
+                  with:CustomChangeNotificationSetterMethodsCodeGenerator)
+          inContext:aCustomContext
+
+    "Modified: / 13-07-2014 / 16:39:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationAccessMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomChangeNotificationAccessMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomChangeNotificationAccessMethodsCodeGenerator new
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_change_notification_access_methods_generated_with_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: true;
+        generateCommentsForSetters: true.
+
+    expectedGetterSource := 'instanceVariable
+    "return the instance variable ''instanceVariable'' (automatically generated)"
+
+    ^ instanceVariable'.
+
+    expectedSetterSource := 'instanceVariable:something 
+    "set the value of the instance variable ''instanceVariable'' and send a change notification (automatically generated)"
+
+    (instanceVariable ~~ something) ifTrue:[
+        instanceVariable := something.
+        self changed:#instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 13-07-2014 / 16:45:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_notification_access_methods_generated_without_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: false;
+        generateCommentsForSetters: false.
+
+    expectedGetterSource := 'instanceVariable
+    ^ instanceVariable'.
+
+    expectedSetterSource := 'instanceVariable:something 
+    (instanceVariable ~~ something) ifTrue:[
+        instanceVariable := something.
+        self changed:#instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 13-07-2014 / 16:47:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,130 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomChangeNotificationSetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomChangeNotificationSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Setter methods with Change Notification for selected instance variables'
+
+    "Modified: / 06-07-2014 / 13:48:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Setters')
+
+    "Created: / 22-08-2014 / 18:54:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Setter Method(s) with Change Notification'
+
+    "Modified: / 06-07-2014 / 13:47:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns setter method with change notification for given class and variable name"
+
+    | methodName comment argName |
+
+    methodName := self methodNameFor: aName.
+    argName := self argNameForMethodName: methodName.  
+    comment := ''.
+
+    userPreferences generateCommentsForSetters ifTrue:[
+        | varType |
+
+        varType := self varTypeOf: aName class: aClass. 
+        comment := '"set the value of the %1 variable ''%2'' and send a change notification (automatically generated)"'.
+        comment := comment bindWith: varType with: aName.
+    ].
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+            `"comment
+
+            (`variableName ~~ `argName) ifTrue:[
+                `variableName := `argName.
+                self changed: `#variableName.
+            ].';
+        replace: '`@methodName' with: (methodName, ': ', argName) asSymbol;
+        replace: '`argName' with: argName asString;
+        replace: '`variableName' with: aName asString;
+        replace: '`#variableName' with: ($#, aName asSymbol);
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Modified: / 19-09-2014 / 22:16:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomChangeNotificationSetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,111 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomChangeNotificationSetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomChangeNotificationSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomChangeNotificationSetterMethodsCodeGenerator new
+! !
+
+!CustomChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_change_notification_setter_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: true.
+
+    expectedSource := 'instanceVariable:something 
+    "set the value of the instance variable ''instanceVariable'' and send a change notification (automatically generated)"
+
+    (instanceVariable ~~ something) ifTrue:[
+        instanceVariable := something.
+        self changed:#instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+    "Created: / 06-07-2014 / 13:55:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_notification_setter_method_generated_without_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: false.
+
+    expectedSource := 'instanceVariable:something 
+    (instanceVariable ~~ something) ifTrue:[
+        instanceVariable := something.
+        self changed:#instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+    "Created: / 06-07-2014 / 14:05:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_instance_variable_present
+    | expectedVariables actualVariables |
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+
+    expectedVariables := #('instanceVariable').
+    actualVariables := (Smalltalk at: #DummyClassForGeneratorTestCase) instanceVariableNames.
+
+    self assert: expectedVariables = actualVariables
+
+    "Created: / 30-11-2014 / 19:16:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomClassQuery.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,90 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomClassQuery
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Helpers'
+!
+
+!CustomClassQuery class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Helper class for retrieving additional informations from classes.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomClassQuery methodsFor:'queries'!
+
+methodForSuperclassSelector: aSelector class: aClass
+    "retrieve method under given selector in class 
+    superclass or in superclass superclass until method is found
+    or nil is reached"
+
+    | superclass |
+
+    superclass := aClass superclass.
+    [ superclass notNil ] whileTrue: [ 
+        | method |
+
+        method := superclass compiledMethodAt: aSelector asSymbol.
+        method notNil ifTrue: [ 
+            ^ method
+        ].
+        superclass := superclass superclass.
+    ].
+
+    ^ nil
+
+    "Created: / 15-06-2014 / 14:58:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 07-10-2014 / 19:50:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomClassQueryTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomClassQueryTests
+	instanceVariableNames:'classQuery model mockSuperClass mockClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Helpers-Tests'
+!
+
+!CustomClassQueryTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomClassQueryTests methodsFor:'initialization & release'!
+
+setUp
+
+    classQuery := CustomClassQuery new.
+    model := CustomNamespace new.
+    mockSuperClass := model createClassImmediate: 'MockSuperClassForTestCase' superClassName: 'Object'.
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: (mockSuperClass new className).
+
+    "Modified: / 09-10-2014 / 09:33:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    model undoChanges
+
+    "Modified: / 19-10-2014 / 14:56:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomClassQueryTests methodsFor:'tests'!
+
+test_method_from_superclass_not_found_01
+    | method |                                                                              
+
+    method := classQuery methodForSuperclassSelector: 'someNonExistingMethod:withParam:' class: Object.
+    self assert: method isNil.
+
+    "Created: / 07-10-2014 / 19:54:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_from_superclass_not_found_02
+    | method |                                                                              
+
+    method := classQuery methodForSuperclassSelector: 'someNonExistingMethod:withParam:' class: self class.
+    self assert: method isNil.
+
+    "Created: / 07-10-2014 / 19:54:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_from_superclass_retrieved
+    | method |
+
+    self assert: (classQuery methodForSuperclassSelector: 'initialize' class: Object) isNil.
+
+    "/ Instance method
+    model createMethodImmediate: mockSuperClass protocol: 'instance-protocol' source: 'instanceMethod: aParam
+    self shouldImplement'.
+
+    method := classQuery methodForSuperclassSelector: #instanceMethod: class: mockClass.
+    self assert: 'instance-protocol' = method category.
+
+    self assert: 'instanceMethod:aParam' = method methodDefinitionTemplate.
+
+    "/ Class method
+    model createMethodImmediate: mockSuperClass class protocol: 'class-protocol' source: 'classMethod: aParam
+    self shouldImplement'.
+
+    method := classQuery methodForSuperclassSelector: 'classMethod:' class: mockClass class.
+    self assert: 'class-protocol' = method category.
+    self assert: 'classMethod:aParam' = method methodDefinitionTemplate.
+
+    "Created: / 14-04-2014 / 18:12:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 15-06-2014 / 16:17:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,79 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoring subclass:#CustomCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGenerator class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CustomCodeGenerator
+
+    "Created: / 26-01-2014 / 21:38:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCustomCodeGenerator
+    ^ true
+! !
+
+!CustomCodeGenerator methodsFor:'testing'!
+
+isCustomCodeGenerator
+    ^ true
+! !
+
+!CustomCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorClassGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,122 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomNewClassGenerator subclass:#CustomCodeGeneratorClassGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomCodeGeneratorClassGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorClassGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Generates template class for code generator'
+
+    "Modified: / 29-03-2014 / 19:38:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #(Generators)
+
+    "Created: / 22-08-2014 / 18:48:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'New Code Generator'
+
+    "Modified: / 29-03-2014 / 19:21:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 22-08-2014 / 18:50:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGenerator methodsFor:'accessing - ui'!
+
+defaultClassName
+
+    ^ 'CustomXXXCodeGenerator'
+
+    "Created: / 09-11-2014 / 01:13:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassNameLabel
+
+    ^ 'Enter class name for new generator'
+
+    "Created: / 09-11-2014 / 01:14:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGenerator methodsFor:'executing - private'!
+
+buildForClass: aClass
+
+    aClass
+        superclassName: #'SmallSense::CustomCodeGenerator';
+        category: self class category.
+
+    "Created: / 09-11-2014 / 01:15:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:55:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorClassGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,98 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorClassGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomCodeGeneratorClassGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorClassGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+    ^ CustomCodeGeneratorClassGenerator new
+
+    "Created: / 27-09-2014 / 11:27:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-11-2014 / 23:17:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGeneratorTests methodsFor:'tests'!
+
+test_code_generator_class_created
+
+    | newGenerator testClassName |
+
+    testClassName := #SmallSense::CustomCodeGeneratorForTestCase.
+
+    self assertClassNotExists: testClassName.
+
+    generatorOrRefactoring dialog answer: testClassName forSelector: #requestClassName:initialAnswer:.
+
+    generatorOrRefactoring executeInContext: CustomBrowserContext new.
+
+    newGenerator := Smalltalk classNamed: testClassName.
+
+    self assertClassExists: testClassName.
+    self assert: (newGenerator includesSelector: #buildInContext:).
+    self assert: (newGenerator class includesSelector: #buildInContext:) not.
+    self assert: (newGenerator includesSelector: #availableInContext:) not.
+    self assert: (newGenerator class includesSelector: #availableInContext:).
+
+    "Created: / 31-03-2014 / 23:20:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-11-2014 / 23:22:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:49:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorClassGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoring.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,663 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomCodeGeneratorOrRefactoring
+	instanceVariableNames:'compositeChangeCollector compositeChangeNesting userPreferences
+		confirmChanges dialog changeManager model refactoryBuilder
+		formatter resources'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+!
+
+subGeneratorOrRefactoringOf:aCodeGeneratorOrRefactoring
+    "Returns and initializes new instance of code generator or refactoring
+    to be used inside another code generator or refactoring."
+    | nestingCount |
+
+    nestingCount := aCodeGeneratorOrRefactoring compositeChangeNesting.
+    nestingCount isNil ifTrue:[ nestingCount := 0 ].
+
+    ^ self new
+        model:aCodeGeneratorOrRefactoring model;
+        refactoryBuilder:aCodeGeneratorOrRefactoring refactoryBuilder;
+        userPreferences:aCodeGeneratorOrRefactoring userPreferences;
+        dialog:aCodeGeneratorOrRefactoring dialog;
+        changeManager:aCodeGeneratorOrRefactoring changeManager;
+        compositeChangeCollector:aCodeGeneratorOrRefactoring compositeChangeCollector;
+        compositeChangeNesting:(1 + nestingCount);
+        yourself
+
+    "Created: / 19-04-2014 / 10:15:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 13-10-2014 / 20:32:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ self subclassResponsibility
+
+    "Created: / 01-12-2013 / 00:18:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #()
+
+    "Created: / 01-12-2013 / 00:21:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 05-08-2014 / 13:23:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ self subclassResponsibility
+
+    "Created: / 01-12-2013 / 00:18:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'enumerating'!
+
+generatorsAndRefactoringsDo: aOneArgBlock
+    "Evaluates a block through all generator or refactoring classes (actually all my subclasses)."
+
+    self allSubclassesDo: aOneArgBlock
+
+    "Created: / 28-12-2014 / 11:44:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'executing'!
+
+executeInContext: aCustomContext
+    ^ self new executeInContext: aCustomContext
+
+    "Created: / 26-01-2014 / 13:42:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+executeInContextWithWaitCursor: aCustomContext
+    ^ self new executeInContextWithWaitCursor: aCustomContext
+
+    "Created: / 10-08-2014 / 09:34:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'private'!
+
+canUseRefactoringSupport
+    "check if refactory browser stuff is avaliable"
+
+     ^ RefactoryChangeManager notNil
+    and:[RefactoryChangeManager isLoaded
+    and:[UserPreferences current useRefactoringSupport]]
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'queries'!
+
+availableForProgrammingLanguages
+    "Returns list of programming language instances for which this generator / refactoring works.
+    (SmalltalkLanguage instance, JavaLanguage instance, GroovyLanguage instance, etc.)
+
+     See also availableForProgrammingLanguagesInContext:withPerspective:"
+
+    "We are assuming here that majority will be written for Smalltalk."
+    ^ {SmalltalkLanguage instance}
+
+    "Created: / 22-12-2014 / 20:12:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableForProgrammingLanguagesInContext: aCustomContext
+    "Returns true if generator / refactoring works for programming languages
+     of codebase elements (classes, methods, etc.) in CustomContext instance.
+
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomMenuBuilder for details."
+
+    | languages perspective |
+
+    perspective := aCustomContext perspective.
+    perspective isNil ifTrue: [
+        "Rather no quess if perspective is missing"
+        ^ true
+    ].
+
+    languages := self availableForProgrammingLanguages.
+
+    perspective isCodeViewPerspective ifTrue: [
+        ^ aCustomContext selectedCodes ? #() anySatisfy: [ :codeSelection |
+            | method |
+
+            method := codeSelection selectedMethod.
+
+            method notNil and: [ languages includes: method programmingLanguage ]
+        ].
+    ].
+
+    perspective isMethodPerspective ifTrue: [
+        aCustomContext selectedMethods isEmptyOrNil ifTrue: [ ^ true ].  
+
+        ^ aCustomContext selectedMethods anySatisfy: [ :method | 
+            method notNil and: [ languages includes: method programmingLanguage ]
+        ].
+    ].
+
+    (perspective isClassPerspective 
+        or: [ perspective isInstanceVariablePerspective ] 
+        or: [ perspective isProtocolPerspective ]) ifTrue: [
+
+        aCustomContext selectedClasses isEmptyOrNil ifTrue: [ ^ true ].
+
+        ^ aCustomContext selectedClasses anySatisfy: [ :class | 
+            class notNil and: [ languages includes: class programmingLanguage ]
+        ].
+    ].
+
+    "For other perspectives (package, class category, namespace) no guess"
+    ^ true
+
+    "Created: / 22-12-2014 / 20:34:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-12-2014 / 09:31:32 / root"
+    "Modified: / 24-01-2015 / 18:24:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInContext: aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ self subclassResponsibility
+
+    "Created: / 01-12-2013 / 00:13:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    ^ self subclassResponsibility
+
+    "Created: / 26-01-2014 / 13:03:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CustomCodeGeneratorOrRefactoring
+
+    "Created: / 26-01-2014 / 21:38:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCustomCodeGenerator
+    ^ false
+!
+
+isCustomRefactoring
+    ^ false
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'accessing'!
+
+changeManager
+
+    ^ changeManager
+
+    "Created: / 31-05-2014 / 13:29:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+changeManager: aChangeManager
+
+    changeManager := aChangeManager
+
+    "Created: / 31-05-2014 / 13:30:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeCollector
+
+    ^ compositeChangeCollector
+
+    "Created: / 19-04-2014 / 10:18:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeCollector: aCompositeChangeCollector
+
+    compositeChangeCollector := aCompositeChangeCollector
+
+    "Created: / 19-04-2014 / 10:18:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeNesting
+
+    ^ compositeChangeNesting
+
+    "Created: / 11-05-2014 / 14:01:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+compositeChangeNesting: aNumber
+
+    compositeChangeNesting := aNumber
+
+    "Created: / 11-05-2014 / 14:01:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+dialog
+
+    ^ dialog
+
+    "Created: / 11-05-2014 / 00:27:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+dialog: aDialog
+
+    dialog := aDialog
+
+    "Created: / 11-05-2014 / 00:27:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter
+
+    ^ formatter
+
+    "Created: / 19-09-2014 / 22:18:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter: aSourceCodeFormatter
+
+    formatter := aSourceCodeFormatter
+
+    "Created: / 19-09-2014 / 22:18:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model
+    ^model
+
+    "Created: / 23-08-2014 / 00:13:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model: aModel
+
+    model := aModel
+
+    "Created: / 23-08-2014 / 00:13:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 09-10-2014 / 10:17:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+refactoryBuilder
+
+    ^ refactoryBuilder
+
+    "Modified (format): / 23-08-2014 / 00:14:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+refactoryBuilder: aRefactoryBuilder
+
+    refactoryBuilder := aRefactoryBuilder.
+
+    "Modified (format): / 23-08-2014 / 00:14:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGenerator
+
+    ^ model sourceCodeGenerator
+
+    "Created: / 19-09-2014 / 20:56:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 07-10-2014 / 22:47:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+userPreferences
+
+    ^ userPreferences
+
+    "Created: / 09-06-2014 / 21:49:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+userPreferences: aUserPreferences
+
+    userPreferences := aUserPreferences
+
+    "Created: / 09-06-2014 / 21:49:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'bulk changes'!
+
+executeCollectedChangesNamed:name
+    "
+    Same as CodeGeneratorTool >> executeCollectedChangesNamed:,
+    but with custom RefactoryChangeManager and custom Dialog
+    "
+
+    compositeChangeCollector notNil ifTrue:[
+        compositeChangeNesting := compositeChangeNesting - 1.
+        compositeChangeNesting == 0 ifTrue:[
+            compositeChangeCollector name:name.
+            compositeChangeCollector changesSize == 0 ifTrue:[
+                dialog information: (resources string: 'Nothing generated.').
+            ] ifFalse:[
+                changeManager performChange: compositeChangeCollector
+            ].
+            compositeChangeCollector := nil.
+            self model changes: CompositeRefactoryChange new.
+        ]
+    ]
+
+    "Created: / 31-05-2014 / 11:30:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 10:42:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 25-01-2015 / 14:31:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+startCollectChanges
+    (self canUseRefactoringSupport) ifTrue:[
+        compositeChangeCollector isNil ifTrue:[
+            compositeChangeCollector := model changes.
+            compositeChangeNesting := 0.
+        ].
+        compositeChangeNesting := compositeChangeNesting + 1.
+    ]
+
+    "Modified: / 16-11-2014 / 10:43:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'code generation'!
+
+addChange: aCodeChange
+
+    aCodeChange notNil ifTrue: [
+        compositeChangeCollector addChange: aCodeChange
+    ]
+
+    "Created: / 23-08-2014 / 15:40:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 17-09-2014 / 22:53:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'compilation'!
+
+compile:theCode forClass:aClass inCategory:cat
+    "install some code for a class.
+     If refactory browser stuff is avaliable the refactory tools are used to support undo"
+
+    self
+        compile:theCode forClass:aClass inCategory:cat
+        skipIfSame:true
+!
+
+compile:theCode forClass:aClass inCategory:categoryOrNil skipIfSame:skipIfSame
+    "Install some code for a class.
+    If refactory browser stuff is avaliable the refactory tools are used to support undo
+    (determined by aClass - can be RBClass/RBMetaclass instance or real class)"
+
+    |compiler selector oldMethod isSame category|
+
+    isSame := false.
+    category := categoryOrNil ? (Compiler defaultMethodCategory).
+
+    skipIfSame ifTrue:[
+        compiler := aClass compilerClass new.
+        compiler parseMethod:theCode in:aClass ignoreErrors:true ignoreWarnings:true.
+
+        selector := compiler selector.
+        selector notNil ifTrue:[
+            oldMethod := aClass compiledMethodAt:selector.
+            isSame := (oldMethod notNil and:[oldMethod source = theCode]).
+            isSame ifTrue:[^ self ].
+            oldMethod notNil ifTrue:[
+                category := categoryOrNil ? (oldMethod category).
+            ].
+        ].
+    ].
+
+    aClass compile: theCode classified: category.
+
+    "Modified: / 21-08-2006 / 18:39:06 / cg"
+    "Modified (format): / 21-01-2012 / 10:40:59 / cg"
+    "Modified (comment): / 08-02-2015 / 19:40:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'executing'!
+
+executeInContext: aCustomContext
+    | context |
+
+    context := aCustomContext copyWithModel: self model.
+
+    self startCollectChanges.
+
+    context isInteractiveContext ifTrue:[
+        self configureInContext: context
+    ].
+
+    self validateInContext: context.
+    self buildInContext: context.
+
+    self executeCollectedChangesNamed: self class description.
+
+    "Created: / 19-03-2014 / 18:45:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-09-2014 / 11:04:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 21:07:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeInContextWithWaitCursor: aCustomContext
+    "Much like executeInContext: but with loading cursor animation"
+
+    | wg executor |
+
+    wg := WindowGroup activeGroup.
+    wg isNil ifTrue:[
+        executor := [:whatToDo | whatToDo value ]
+    ] ifFalse:[
+        executor := [:whatToDo | wg withWaitCursorDo: [ whatToDo value ] ]
+    ].
+
+    executor value:[
+        self executeInContext: aCustomContext
+    ]
+
+    "Created: / 07-08-2014 / 23:17:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeSubGeneratorOrRefactoringClasses:aSubGeneratorOrRefactoringClasses inContext:aCustomContext
+    "For each code generator or refactoring class initializes an instance
+    and executes it."
+
+    aSubGeneratorOrRefactoringClasses do:[ :class | 
+        (class subGeneratorOrRefactoringOf:self)
+            executeInContext:aCustomContext
+    ]
+
+    "Created: / 08-07-2014 / 18:31:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 13-10-2014 / 20:25:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'executing - private'!
+
+buildInContext:aCustomContext
+    "Should generate code or perform custom refactoring."
+
+    ^ self subclassResponsibility
+
+    "Created: / 16-09-2014 / 09:14:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 13-10-2014 / 17:21:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext
+    "Perform neccessary configuration for given context, such as
+     computing default values for parameters. This may interact with
+     user by means of opening a dialog.
+
+     This method is called only for interactive contexts. When using
+     non interactively, a caller must do the configuration itself by means
+     of accessors."
+
+    "/ To be overridden by subclasses
+
+    "Created: / 16-09-2014 / 07:24:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 16-09-2014 / 11:00:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+validateInContext: aCustomContext
+
+    "/ To be overridden by subclasses
+
+    "Created: / 16-09-2014 / 09:45:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'initialization'!
+
+confirmChanges
+    "if true, let user confirm complicated changes; if false, just do it"
+
+    ^ confirmChanges ? true
+
+    "Created: / 04-08-2011 / 17:31:45 / cg"
+!
+
+confirmChanges:aBoolean
+    "if true, let user confirm complicated changes; if false, just do it"
+
+    confirmChanges := aBoolean
+
+    "Created: / 04-08-2011 / 17:26:47 / cg"
+!
+
+initialize
+
+    userPreferences := UserPreferences current.
+    "Translated dialogs have to be in part of browser, so use browser resources"
+    resources := Tools::NewSystemBrowser classResources.
+
+    self initializeFormatter;
+        initializeChangeManager;
+        initializeModel;
+        initializeRefactoryBuilder;
+        initializeDialog.
+
+    "Created: / 17-03-2014 / 22:27:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-02-2015 / 20:17:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeChangeManager
+    changeManager := CustomBrowserChangeManager new.
+
+    "Created: / 09-06-2014 / 22:56:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeDialog
+    dialog := CustomUserDialog new.
+
+    "Created: / 09-06-2014 / 22:57:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeFormatter
+    formatter := CustomRBLocalSourceCodeFormatter new
+
+    "Created: / 18-09-2014 / 23:12:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeModel
+    model := (CustomNamespace new)
+            formatter:formatter;
+            changeManager:changeManager;
+            yourself
+
+    "Created: / 09-06-2014 / 22:56:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 10:41:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeRefactoryBuilder
+    refactoryBuilder := (CustomRefactoryBuilder new)
+            formatter:formatter;
+            changeManager:changeManager;
+            model:model;
+            yourself
+
+    "Created: / 23-08-2014 / 00:05:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 10:41:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'private'!
+
+canUseRefactoringSupport
+    "check if refactory browser stuff is avaliable"
+
+     ^ self class canUseRefactoringSupport
+! !
+
+!CustomCodeGeneratorOrRefactoring methodsFor:'testing'!
+
+isCustomCodeGenerator
+    ^ false
+!
+
+isCustomRefactoring
+    ^ false
+! !
+
+!CustomCodeGeneratorOrRefactoring class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoringTestCase.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,366 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomCodeGeneratorOrRefactoringTestCase
+	instanceVariableNames:'context model refactoryBuilder generatorOrRefactoring classes
+		changeManager userPreferences mock formatter dialog'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomCodeGeneratorOrRefactoringTestCase class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'accessing'!
+
+generatorOrRefactoring
+    "Should return an instance of CustomCodeGenerator or CustomRefactoring subclass"
+
+    ^ self subclassResponsibility
+
+    "Created: / 27-05-2014 / 19:16:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 23-08-2014 / 11:38:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'asserting'!
+
+assertClassExists: aClassName
+
+    self assert: (Smalltalk classNamed: aClassName asString) isNil not
+
+    "Created: / 15-06-2014 / 16:42:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertClassMethodSource: aSourceCode atSelector: aSelector
+    "Assert that source code is same at given selector for first generated class"
+
+    | className class |
+
+    className := classes first name.
+    class := Smalltalk classNamed: className.
+
+    ^ self assertClassMethodSource: aSourceCode atSelector: aSelector forClass: class
+
+    "Created: / 11-07-2014 / 20:11:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-10-2014 / 18:58:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertClassMethodSource: expectedSource atSelector: aSelector forClass: aClass
+    "Assert that source code is same at given selector for given class"
+
+    | actualSource |
+
+    actualSource := aClass theMetaclass sourceCodeAt: aSelector asSymbol.
+
+    ^ self assertSource: expectedSource sameAs: actualSource
+
+    "Created: / 11-07-2014 / 20:09:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertClassNotExists: aClassName
+
+    self assert: (Smalltalk classNamed: aClassName asString) isNil
+
+    "Created: / 15-06-2014 / 16:42:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertMethodCount: aNumber inClass: aClass
+    | realClass |
+
+    realClass := Smalltalk at: (aClass theNonMetaclass name asSymbol).
+
+    self assert: aNumber = (realClass methodDictionary size).
+
+    "Created: / 26-09-2014 / 10:48:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertMethodSource: aSourceCode atSelector: aSelector
+    "Assert that source code is same at given selector for first generated class"
+
+    | className class |
+
+    className := classes first name.
+    class := Smalltalk at: className.
+
+    ^ self assertMethodSource: aSourceCode atSelector: aSelector forClass: class
+
+    "Created: / 27-05-2014 / 20:06:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-09-2014 / 00:15:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertMethodSource: expectedSource atSelector: aSelector forClass: aClass
+    "Assert that source code is same at given selector for given class"
+
+    | actualSource |
+
+    actualSource := aClass sourceCodeAt: aSelector asSymbol.
+
+    ^ self assertSource: expectedSource sameAs: actualSource
+
+    "Created: / 27-05-2014 / 20:08:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+assertSource: expectedSource sameAs: actualSource
+
+    self assert: (Change isSource: expectedSource sameSourceAs: actualSource)
+
+    "Created: / 25-05-2014 / 22:18:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-07-2014 / 11:31:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'code generation helpers'!
+
+createClass
+    "Returns new class change with some name"
+
+    | class |
+
+    class := model createClass
+        name: #DummyClassForGeneratorTestCase;
+        compile;
+        yourself.
+
+    classes add: class.
+
+    ^ class
+
+    "Created: / 29-05-2014 / 23:22:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 09-10-2014 / 10:34:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'context templates'!
+
+classWithInstanceVariable
+    | class |
+
+    class := self createClass.
+    class instanceVariableNames: (Array with: 'instanceVariable'); compile.
+
+    context selectedClasses: (Array with: class).
+
+    ^ class
+
+    "Created: / 29-05-2014 / 00:33:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-11-2014 / 19:17:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classWithThreeInstanceVariables
+    | class |
+
+    class := self createClass.
+    class instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02' with: 'instanceVariable_03'); compile.
+
+    context selectedClasses: (Array with: class).
+    context selectedVariables: (class instanceVariableNames).
+
+    ^ class
+
+    "Created: / 13-07-2014 / 21:56:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-11-2014 / 19:18:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classWithTwoInstanceVariables
+    | class |
+
+    class := self createClass.
+    class instanceVariableNames: (Array with: 'instanceVariable_01' with: 'instanceVariable_02'); compile.
+
+    context selectedClasses: (Array with: class).
+    context selectedVariables: (class instanceVariableNames).
+
+    ^ class
+
+    "Created: / 13-07-2014 / 21:45:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-11-2014 / 19:18:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'executing'!
+
+createContext: contextTemplateName
+    "Creates context by given template name
+    (produces more readable code than just method call)"
+
+    self perform: contextTemplateName asSymbol
+
+    "Created: / 27-07-2014 / 12:27:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeGeneratorInContext: contextTemplateName
+    "Executes generator in context created by given name"
+
+    self perform: contextTemplateName asSymbol.
+    generatorOrRefactoring executeInContext: context
+
+    "Created: / 27-05-2014 / 20:03:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-05-2014 / 23:38:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'initialization & release'!
+
+defaultUserPreferences
+
+    userPreferences
+        generateComments: true;
+        generateCommentsForAspectMethods: true;
+        generateCommentsForGetters: true;
+        generateCommentsForSetters: true
+
+    "Created: / 09-06-2014 / 22:36:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUp
+    Screen current isNil ifTrue:[
+        Smalltalk openDisplay.
+        Screen current isNil ifTrue:[
+            self assert: false description: 'Tests need display connection'.
+        ]
+    ].
+
+    classes := OrderedCollection new.
+    mock := CustomMock new.
+    dialog := CustomSilentDialog new.
+
+    context := CustomSubContext new.
+
+    changeManager := CustomLocalChangeManager new.
+    self setUpBuilders.
+
+    userPreferences := UserPreferences new.
+    self defaultUserPreferences.
+    generatorOrRefactoring := self generatorOrRefactoring.
+
+    self setUpTestFormatter.
+
+    generatorOrRefactoring notNil ifTrue: [
+        self setUpGeneratorOrRefactoring: generatorOrRefactoring
+    ].
+
+    "Created: / 27-05-2014 / 19:16:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 14:39:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpBuilders
+
+    model := CustomNamespace new.
+    model changeManager: changeManager.
+
+    refactoryBuilder := CustomRefactoryBuilder new.
+    refactoryBuilder changeManager: changeManager.
+    refactoryBuilder model: model.
+
+    "Created: / 23-08-2014 / 15:57:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-10-2014 / 19:49:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpGeneratorOrRefactoring: aGeneratorOrRefactoring
+
+    aGeneratorOrRefactoring 
+        formatter: formatter;
+        model: model;
+        refactoryBuilder: refactoryBuilder;
+        changeManager: changeManager;
+        userPreferences: userPreferences;
+        dialog: dialog
+
+    "Created: / 23-08-2014 / 15:59:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-10-2014 / 11:03:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpTestFormatter
+
+    formatter := CustomRBLocalSourceCodeFormatter new.
+    formatter
+        tabIndent: 4;
+        spaceAroundTemporaries: false;
+        emptyLineAfterTemporaries: true;
+        emptyLineAfterMethodComment: true;
+        spaceAfterReturnToken: true;
+        spaceAfterKeywordSelector: false;
+        spaceAfterBlockStart: true;
+        spaceBeforeBlockEnd: true;
+        cStyleBlocks: true;
+        blockArgumentsOnNewLine: false;
+        maxLengthForSingleLineBlocks: 4;
+        periodAfterLastStatementPolicy: #keep.
+    "
+    EmptyLineBeforeFinalMethodComment := true.
+    SpaceAroundLiteralArrayElements := true.
+    STXStyleMethodComments := true.
+    "
+    model formatter: formatter.
+    refactoryBuilder formatter: formatter
+
+    "Created: / 28-08-2014 / 23:29:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 31-08-2014 / 17:23:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    changeManager undoChanges.
+    mock unmockAll
+
+    "Created: / 27-05-2014 / 19:26:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-10-2014 / 14:56:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase methodsFor:'running'!
+
+runCase
+    "Run the case and do not add any mess into the changes file (st.chg)."
+
+    Class withoutUpdatingChangesDo: [ 
+        super runCase
+    ]
+
+    "Created: / 30-11-2014 / 17:02:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCase class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,154 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomTestCaseCodeGenerator subclass:#CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    ^ 'Creates a new test case for custom code generator/refactoring'
+
+    "Modified: / 23-08-2014 / 19:50:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-09-2014 / 11:33:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Generators')
+
+    "Created: / 22-08-2014 / 18:50:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    ^ 'New Code Generator Testcase'
+
+    "Modified: / 23-08-2014 / 19:50:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 22-08-2014 / 18:50:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext 
+    | classes |
+
+    classes := aCustomContext selectedClasses.
+    ^ classes notEmpty 
+        and:[ classes allSatisfy: [:e | e inheritsFrom: CustomCodeGeneratorOrRefactoring ] ].
+
+    "Created: / 15-09-2014 / 15:19:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultTestSuperName
+    ^ 'CustomCodeGeneratorOrRefactoringTestCase'
+
+    "Created: / 16-09-2014 / 10:32:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator methodsFor:'executing - private'!
+
+generateTestCaseCodeFor:aTestClass forClassUnderTest:aClass 
+    | source className package |
+
+    super generateTestCaseCodeFor:aTestClass forClassUnderTest:aClass.
+    className := aClass theNonMetaClass name.
+
+    package := PackageId noProjectID.
+    samePackageAsTestedClass ifTrue: [ 
+        package := aClass package
+    ].
+
+    source := 'test_code_generated
+    | expectedSource |
+
+    expectedSource := ''instanceVariable
+    ^ instanceVariable''.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable'.
+
+    model createMethod
+        class: aTestClass;
+
+        protocol: 'tests';
+        source: source;
+        package: package;
+        compile.
+
+    model createMethod
+        class: aTestClass;
+
+        protocol: 'accessing';
+        source: 'generatorOrRefactoring
+    ^ `className new';
+        replace: '`className' with: className asString;
+        package: package;
+        compile
+
+    "Created: / 16-09-2014 / 10:40:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-01-2015 / 18:39:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorOrRefactoringTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,492 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorOrRefactoringTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomCodeGeneratorOrRefactoringTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorOrRefactoringTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    | generatorMock |
+
+    generatorMock := mock mockOf: CustomCodeGeneratorOrRefactoring.
+    generatorMock class compileMockMethod: 'description ^ ''''. '.
+    ^ generatorMock
+
+    "Created: / 10-11-2014 / 22:04:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-11-2014 / 23:46:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTests methodsFor:'tests'!
+
+test_all_my_non_abstract_implementors_have_filled_label_and_description
+
+    CustomCodeGeneratorOrRefactoring allSubclassesDo:[ :subclass |
+        "Include only non abstract and non mock classes"
+        (subclass isAbstract or: [ (subclass includesSelector: #compileMockMethod:) ]) ifFalse:[
+            self assert: subclass label notEmptyOrNil.
+            self assert: subclass description notEmptyOrNil
+        ]
+    ]
+
+    "Created: / 18-10-2014 / 13:38:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:02:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages
+    | expectedLanguages actualLanguages |
+
+    expectedLanguages := {SmalltalkLanguage instance}.
+    actualLanguages := generatorOrRefactoring class availableForProgrammingLanguages.    
+    
+    self assert: expectedLanguages = actualLanguages
+
+    "Modified: / 22-12-2014 / 13:38:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective
+
+    context
+        perspective: CustomPerspective classPerspective;
+        selectedClasses: (Array with: self class).
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 13:43:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_empty
+
+    context perspective: CustomPerspective classPerspective.
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 13:40:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_empty_class
+
+    context
+        perspective: CustomPerspective classPerspective;
+        selectedClasses: (Array with: nil).
+
+    self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 24-01-2015 / 18:27:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_java
+    | class |
+
+    "Prepare model class otherwise we would need real existing java class to test functionality"
+    class := RBClass new
+        realClass: JavaClass new;
+        yourself.
+
+    context
+        perspective: CustomPerspective classPerspective;
+        selectedClasses: (Array with: class).
+
+    self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 13:44:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_class_perspective_java_and_smalltalk
+    | class |
+
+    "Prepare model class otherwise we would need real existing java class to test functionality"
+    class := RBClass new
+        realClass: JavaClass new;
+        yourself.
+
+    context
+        perspective: CustomPerspective classPerspective;
+        selectedClasses: (Array with: class with: self class).
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 13:53:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_code_view_perspective
+
+    context
+        perspective: CustomPerspective codeViewPerspective;
+        selectedCodes: (Array with:
+            (CustomSourceCodeSelection new
+                selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring);
+                yourself)).
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 12:08:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_code_view_perspective_empty_method
+
+    context
+        perspective: CustomPerspective codeViewPerspective;
+        selectedCodes: (Array with: CustomSourceCodeSelection new).
+
+    self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 12:14:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_method_perspective
+
+    context
+        perspective: CustomPerspective methodPerspective;
+        selectedMethods: (Array with: (self class compiledMethodAt: #generatorOrRefactoring)).
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 12:37:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_method_perspective_and_empty_method
+
+    context
+        perspective: CustomPerspective methodPerspective;
+        selectedMethods: (Array with: nil).
+
+    self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 24-01-2015 / 18:29:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_method_perspective_empty
+
+    context perspective: CustomPerspective methodPerspective.
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 12:38:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_filled_with_protocol_perspective_empty
+
+    context perspective: CustomPerspective protocolPerspective.
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 13:41:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_with_class_category_perspective
+
+    context perspective: CustomPerspective classCategoryPerspective.
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 13:42:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_with_code_view_perspective
+
+    context perspective: CustomPerspective codeViewPerspective.
+
+    self deny: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 26-12-2014 / 23:09:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 27-12-2014 / 12:04:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_context_with_package_perspective
+
+    context perspective: CustomPerspective packagePerspective.
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Created: / 27-12-2014 / 13:42:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_programming_languages_in_sub_context
+
+    self assert: (generatorOrRefactoring class availableForProgrammingLanguagesInContext: context)
+
+    "Modified: / 26-12-2014 / 23:05:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_change_reflected_in_model
+    | expectedSource class realClass |
+
+    class := model createClass
+        name: #DummyClass01;
+        compile;
+        yourself.
+
+    expectedSource := 'selector01 ^ 456'.
+
+    generatorOrRefactoring compile: expectedSource 
+        forClass: class 
+        inCategory: nil
+        skipIfSame: true.    
+    
+    self assertMethodSource: expectedSource atSelector: #selector01 forClass: class.
+    self assertClassNotExists: #DummyClass01.  
+
+    generatorOrRefactoring compileMockMethod: 'buildInContext:context'; 
+        executeInContext: context.
+
+    realClass := Smalltalk at: #DummyClass01.
+
+    self assertMethodSource: expectedSource atSelector: #selector01 forClass: realClass.
+
+    "Modified: / 08-02-2015 / 19:49:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_not_skipped
+    | expectedChangeSize actualChangeSize class |
+
+    class := model createClass
+        name: #DummyClass01;
+        compile;
+        yourself.
+
+    class compile: 'selector01 ^ 456'.  
+
+    generatorOrRefactoring compile: 'selector01 ^ 4567' 
+        forClass: class 
+        inCategory: nil
+        skipIfSame: true.    
+
+    expectedChangeSize := 3.
+    actualChangeSize := model changes changesSize.
+
+    self assert: expectedChangeSize = actualChangeSize
+
+    "Created: / 08-02-2015 / 20:03:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_real_class
+    | expectedSource class |
+
+    class := model createClassImmediate: #DummyClass01.
+
+    expectedSource := 'selector01 ^ 456'.
+
+    generatorOrRefactoring compile: expectedSource 
+        forClass: class 
+        inCategory: nil
+        skipIfSame: true.    
+    
+    self assertMethodSource: expectedSource atSelector: #selector01 forClass: class.
+    self assertClassExists: #DummyClass01.
+
+    "Created: / 08-02-2015 / 19:51:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_in_category_skip_if_same_skipped
+    | expectedChangeSize actualChangeSize class source |
+
+    class := model createClass
+        name: #DummyClass01;
+        compile;
+        yourself.
+
+    source := 'selector01 ^ 456'.
+    class compile: source.  
+
+    generatorOrRefactoring compile: source 
+        forClass: class 
+        inCategory: nil
+        skipIfSame: true.    
+
+    expectedChangeSize := 2.
+    actualChangeSize := model changes changesSize.
+
+    self assert: expectedChangeSize = actualChangeSize
+
+    "Created: / 08-02-2015 / 19:59:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_aborted
+    | dialogBox |
+
+    dialogBox := mock mockOf: DialogBox.
+    dialogBox
+        compileMockMethod: 'open ^ nil';
+        compileMockMethod: 'accepted ^ false'.
+
+    dialog := (mock mockOf: CustomUserDialog)
+        compileMockMethod: 'information:arg ^ nil';        
+        dialog: dialogBox;
+        yourself.  
+
+    context := CustomBrowserContext new.
+    generatorOrRefactoring
+        dialog: dialog;  
+        compileMockMethod: 'buildInContext:aContext ^ dialog open'.
+
+    self should: [ 
+        generatorOrRefactoring executeInContext: context.
+    ] raise: AbortOperationRequest.
+
+    "/ self assert: generatorOrRefactoring == (generatorOrRefactoring executeInContext: context).
+
+    "Modified: / 25-11-2014 / 21:32:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_not_aborted
+    | dialogBox |
+
+    dialogBox := mock mockOf: DialogBox.
+    dialogBox
+        compileMockMethod: 'open ^ nil';
+        compileMockMethod: 'accepted ^ true'.
+
+    dialog := (mock mockOf: CustomUserDialog)
+        compileMockMethod: 'information:arg ^ nil';        
+        dialog: dialogBox;
+        yourself.  
+
+    context := CustomBrowserContext new.
+    generatorOrRefactoring
+        dialog: dialog;  
+        compileMockMethod: 'buildInContext:aContext ^ dialog open'.
+
+    self shouldnt: [ 
+        generatorOrRefactoring executeInContext: context.
+    ] raise: AbortOperationRequest.
+
+    "/ self assert: generatorOrRefactoring == (generatorOrRefactoring executeInContext: context).
+
+    "Created: / 10-11-2014 / 23:35:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 21:33:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_shared_change_collector_with_correct_change_order
+    "We need to check whether each part of generator/refactoring
+    API writes to the same change collector. If we dont preserve correct
+    change order then wrong result may be produced."
+    | class expectedSource |
+
+    generatorOrRefactoring compileMockMethod: 'buildInContext: aContext
+    | class context |
+
+    class := model createClass
+        name: #DummyClass01;
+        category: ''Some-Category-01'';
+        compile;
+        yourself.
+
+    self compile:''selector_01 ^ 1'' forClass:class inCategory:''protocol01''.
+    class removeMethod:#selector_01.
+    class compile:''selector_02 ^ ''''literal02''''. ''.
+
+    context := CustomSubContext new selectedClasses: (Array with: class); yourself.
+    refactoryBuilder replace:''`#literal'' with:''''''literal525'''''' inContext:context.
+    refactoryBuilder changeCategoryOf:class to:''Some-Category-02''.
+    '.
+
+    generatorOrRefactoring executeInContext: context.
+
+    class := Smalltalk at: #DummyClass01.
+
+    self assert: (class category) = #'Some-Category-02'.
+    self assert: (class sourceCodeAt: #selector_01) isNil.
+
+    expectedSource := 'selector_02
+    ^ ''literal525''.'.
+
+    self assertMethodSource: expectedSource atSelector: #selector_02 forClass: class.
+
+    "Created: / 04-12-2014 / 23:24:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_in_context_with_real_class_and_compile_on_model_class
+    | class modelClass |
+
+    generatorOrRefactoring compileMockMethod: 'buildInContext: aContext
+    aContext selectedClasses do: [ :class |
+        class compile: ''selector_01 ^ 1''.
+    ]'.
+
+    class := model createClassImmediate: #DummyClass01.
+    self assert: class isBehavior.  
+
+    context selectedClasses: (Array with: class).
+
+    generatorOrRefactoring executeInContext: context.
+
+    modelClass := generatorOrRefactoring model classNamed: #DummyClass01.
+
+    self assert: (class includesSelector: #selector_01).
+    self assert: (modelClass includesSelector: #selector_01)
+
+    "Created: / 24-11-2014 / 23:43:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 20:41:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_do
+    | expectedGenerators actualGenerators |
+
+    expectedGenerators := CustomCodeGeneratorOrRefactoring allSubclasses.
+    actualGenerators := OrderedCollection streamContents: [ :stream |
+        CustomCodeGeneratorOrRefactoring generatorsAndRefactoringsDo: [ :class |
+            stream nextPut: class  
+        ].
+    ].
+    
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified: / 24-01-2015 / 18:26:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorOrRefactoringTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,109 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomCodeGenerator new
+! !
+
+!CustomCodeGeneratorTests methodsFor:'tests'!
+
+test_execute_sub_generator_classes
+    | subGeneratorClass_01 subGeneratorClass_02 expectedSource_01 expectedSource_02 |
+
+    "/ setup context
+    self classWithInstanceVariable.
+
+    subGeneratorClass_01 := mock mockClassOf: CustomCodeGenerator.
+    subGeneratorClass_02 := mock mockClassOf: CustomCodeGenerator.
+
+    subGeneratorClass_01 compileMockMethod: 'description ''01'' '.
+    subGeneratorClass_01 new compileMockMethod: 'buildInContext: aCustomContext
+
+        aCustomContext selectedClasses do: [ :class | 
+            model createMethod
+                class: class;
+                source: ''selector_01 ^ 1'';
+                compile.
+        ]'.
+
+    subGeneratorClass_02 compileMockMethod: 'description ''02'' '.
+    subGeneratorClass_02 new compileMockMethod: 'buildInContext: aCustomContext
+
+        aCustomContext selectedClasses do: [ :class | 
+            model createMethod
+                class: class;
+                source: ''selector_02 ^ 2'';
+                compile.
+        ]'.
+
+    generatorOrRefactoring 
+          executeSubGeneratorOrRefactoringClasses:(Array with:subGeneratorClass_01
+                  with:subGeneratorClass_02)
+          inContext:context. 
+
+    expectedSource_01 := 'selector_01
+    ^ 1'.
+
+    expectedSource_02 := 'selector_02
+    ^ 2'.
+
+    self assertMethodSource: expectedSource_01 atSelector: #selector_01.
+    self assertMethodSource: expectedSource_02 atSelector: #selector_02.
+
+    "Created: / 10-07-2014 / 12:11:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 16:06:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeGeneratorUserPreferencesTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,75 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeGeneratorUserPreferencesTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomCodeGeneratorUserPreferencesTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeGeneratorUserPreferencesTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ nil
+
+    "Modified: / 09-06-2014 / 22:42:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeGeneratorUserPreferencesTests methodsFor:'tests'!
+
+test_user_preferences_same_for_tests
+
+    self assert: userPreferences generateComments.
+    self assert: userPreferences generateCommentsForAspectMethods.
+    self assert: userPreferences generateCommentsForGetters.
+    self assert: userPreferences generateCommentsForSetters.
+
+    "Created: / 09-06-2014 / 22:29:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:49:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeSelectionRefactoring.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,101 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomRefactoring subclass:#CustomCodeSelectionRefactoring
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomCodeSelectionRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Template class for refactorings which operates on selected source code in the text editor.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomCodeSelectionRefactoring class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ aCustomContext selectedCodes ? #() anySatisfy: [ :selectedCode | 
+        selectedCode selectedSourceCode notEmptyOrNil
+    ]
+
+    "Created: / 21-08-2014 / 23:28:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:01:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    ^ aCustomPerspective isCodeViewPerspective
+
+    "Created: / 21-08-2014 / 23:28:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-10-2014 / 10:29:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+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 == CustomCodeSelectionRefactoring.
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeSelectionToResourceTranslation.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeSelectionRefactoring subclass:#CustomCodeSelectionToResourceTranslation
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomCodeSelectionToResourceTranslation class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Wraps variable, literal, string or expression code selection
+    with following translation call: resources string:'Some string...'
+    Ie.: when 'Some string...' is selected in the code editor then its
+    replaced by: resources string:'Some string...'
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomCodeSelectionToResourceTranslation class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Wrap code selection with translation call - resources string:'
+
+    "Created: / 21-08-2014 / 23:46:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Selection to Resources Translation'
+
+    "Created: / 21-08-2014 / 23:43:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeSelectionToResourceTranslation methodsFor:'executing'!
+
+buildInContext:aCustomContext
+    "Performs a refactoring within given context scope"
+
+    refactoryBuilder 
+          replace:'`@expression'
+          with:'(resources string: (`@expression))'
+          inContext:aCustomContext
+
+    "Created: / 23-08-2014 / 00:16:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 22:57:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeSelectionToResourceTranslation class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomCodeSelectionToResourceTranslationTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,256 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomCodeSelectionToResourceTranslationTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings-Tests'
+!
+
+!CustomCodeSelectionToResourceTranslationTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomCodeSelectionToResourceTranslationTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomCodeSelectionToResourceTranslation new
+! !
+
+!CustomCodeSelectionToResourceTranslationTests methodsFor:'tests'!
+
+test_available_in_code_view_perspective
+    | perspective |
+
+    perspective := CustomPerspective codeViewPerspective.
+
+    self assert: (generatorOrRefactoring class availableInPerspective:perspective).
+
+    "Created: / 15-10-2014 / 08:10:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty
+    
+    self deny: (generatorOrRefactoring class availableInContext: context).
+
+    "Modified: / 15-10-2014 / 09:32:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty_selected_codes
+
+    context selectedCodes: (Array
+        with: CustomSourceCodeSelection new  
+    ).
+
+    self deny: (generatorOrRefactoring class availableInContext: context).
+
+    "Created: / 15-10-2014 / 09:37:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 22:53:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_with_selected_codes
+
+    context selectedCodes: (Array
+        with: (CustomSourceCodeSelection new
+            selectedInterval: (1 to: 5);
+            currentSourceCode: 'selector_05 ^ 5';
+            yourself)
+    ).
+
+    self assert: (generatorOrRefactoring class availableInContext: context).
+
+    "Created: / 15-10-2014 / 09:41:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_01
+    | expectedSource originalSource codeSelection class |
+
+    originalSource := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+    model createMethodImmediate: class source: originalSource.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedClass: class;
+        selectedInterval: (32 to: 48);
+        selectedMethod: (class compiledMethodAt: #selector);
+        selectedSelector: #selector.
+
+    context selectedCodes: (Array with: codeSelection).  
+    generatorOrRefactoring executeInContext: context.  
+
+    expectedSource := 'selector
+    self information: (resources string:''Translate this'').
+    ^ self.'.
+
+    self assertMethodSource:expectedSource atSelector:#selector forClass:class
+
+    "Created: / 23-08-2014 / 20:09:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 20:14:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_02
+    | expectedSource originalSource codeSelection class |
+
+    originalSource := 'selector
+    self information: self theInformation.
+    ^ self.'.
+
+    class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+    model createMethodImmediate: class source: originalSource.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedClass: class;
+        selectedInterval: (32 to: 51);
+        selectedMethod: (class compiledMethodAt: #selector);
+        selectedSelector: #selector.
+
+    context selectedCodes: (Array with: codeSelection).  
+    generatorOrRefactoring executeInContext: context.  
+
+    expectedSource := 'selector
+    self information: (resources string:self theInformation).
+    ^ self.'.
+
+    self assertMethodSource:expectedSource atSelector:#selector forClass:class
+
+    "Created: / 15-10-2014 / 09:45:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 20:14:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_with_keep_package
+    | expectedSource originalSource codeSelection class method compiledMethod |
+
+    originalSource := 'selector
+    self information: self theInformation.
+    ^ self.'.
+
+    class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+    method := model createMethodImmediate: class source: originalSource.
+    method package: #some_package.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedClass: class;
+        selectedInterval: (32 to: 51);
+        selectedMethod: (class compiledMethodAt: #selector);
+        selectedSelector: #selector.
+
+    context selectedCodes: (Array with: codeSelection).  
+    generatorOrRefactoring executeInContext: context.  
+
+    expectedSource := 'selector
+    self information: (resources string:self theInformation).
+    ^ self.'.
+
+    self assertMethodSource:expectedSource atSelector:#selector forClass:class.
+
+    compiledMethod := class compiledMethodAt: #selector.
+
+    self assert: #some_package = (compiledMethod package).
+
+    "Created: / 16-10-2014 / 21:46:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 20:14:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_selection_replaced_by_resource_translation_with_wrong_selection
+    | expectedSource originalSource codeSelection class |
+
+    originalSource := 'method: arg
+
+    arg ifNil: [ 
+        self warn: ''nil''.
+    ]
+    ifNotNil: [ self information: ''info'' ]'.
+
+    class := model createClassImmediate: 'DummyClassForTestCase01' instanceVariableNames: 'resources'.
+    model createMethodImmediate: class source: originalSource.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedClass: class;
+        selectedInterval: (8 to: 10);
+        selectedMethod: (class compiledMethodAt: #method:);
+        selectedSelector: #selector.
+
+    context selectedCodes: (Array with: codeSelection).  
+    generatorOrRefactoring executeInContext: context.  
+
+    expectedSource := 'method: arg
+
+    arg ifNil: [ 
+        self warn: ''nil''.
+    ]
+    ifNotNil: [ self information: ''info'' ]'.
+
+    self assertMethodSource:expectedSource atSelector:#method: forClass:class
+
+    "Created: / 17-10-2014 / 22:31:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_not_available_in_class_perspective
+    | perspective |
+
+    perspective := CustomPerspective classPerspective.
+
+    self deny: (generatorOrRefactoring class availableInPerspective:perspective).
+
+    "Created: / 15-10-2014 / 08:11:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomCodeSelectionToResourceTranslationTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomContext.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,237 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomContext
+	instanceVariableNames:'model perspective'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomContext class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomContext class methodsFor:'instance creation'!
+
+new
+    "Returns an initialized instance"
+
+    ^ self basicNew initialize.
+
+    "Modified: / 19-11-2014 / 09:36:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext 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 == CustomContext.
+! !
+
+!CustomContext methodsFor:'accessing'!
+
+model
+    "Returns a class model on we operate e.g. RBNamespace, CustomNamespace"
+
+    ^ model
+
+    "Modified (comment): / 19-11-2014 / 10:00:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model: anRBNamespace
+    "see model"
+
+    model := anRBNamespace
+
+    "Modified (format): / 19-11-2014 / 10:01:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+perspective
+    "see CustomPerspective"
+
+    ^ perspective
+
+    "Modified (comment): / 24-12-2014 / 22:39:02 / root"
+!
+
+perspective: aPerspective
+    "see CustomPerspective"
+
+    perspective := aPerspective
+
+    "Created: / 27-12-2014 / 12:02:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'accessing-selection'!
+
+selectedClassCategories
+    "a collection with selected class categories"
+
+    self subclassResponsibility
+
+    "Created: / 05-05-2014 / 00:13:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses
+    "a collection with selected classes"
+
+    self subclassResponsibility
+
+    "Created: / 26-04-2014 / 13:13:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 26-04-2014 / 22:38:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes
+    "a collection with source codes (CustomSourceCodeSelection) 
+    with selected interval (exact position in source code) and
+    corresponding class, method, selector."
+
+    self subclassResponsibility
+
+    "Created: / 18-08-2014 / 21:28:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods
+    "a collection with selected methods"
+
+    self subclassResponsibility
+
+    "Created: / 05-05-2014 / 00:12:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages
+    "a collection with selected packages"
+
+    self subclassResponsibility
+
+    "Created: / 05-05-2014 / 00:12:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols
+    "a collection with selected method protocols"
+    
+    self subclassResponsibility
+
+    "Created: / 05-05-2014 / 00:14:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables
+    "a collection with selected variables"
+
+    self subclassResponsibility
+
+    "Created: / 05-05-2014 / 00:14:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'initialization'!
+
+initialize
+
+    model := SmallSense::CustomNamespace onEnvironment: BrowserEnvironment new.
+
+    "Modified: / 19-11-2014 / 09:35:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:07:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'instance creation'!
+
+copyWithModel: aModel
+    "Returs shallow copy with custom class model. It is useful
+    if we need to keep object immutability when we receive it
+    as method parameter. Setting just model could have side effect,
+    because the sender probably does not expect object to be modified,
+    but only read."
+
+    ^ self copy model: aModel; yourself
+
+    "Created: / 25-11-2014 / 19:46:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'private'!
+
+asRBClass: cls 
+    "For given real class, return a corresponding RBClass"
+
+    ^ Object isMetaclass 
+        ifTrue:[ model metaclassNamed: cls theNonMetaclass name ]
+        ifFalse:[ model classNamed: cls name ]
+
+    "Created: / 14-11-2014 / 19:26:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 19-11-2014 / 09:39:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+asRBMethod: aMethod
+    | rbClass |
+
+    rbClass := self asRBClass: aMethod mclass.
+    ^ rbClass methodFor: aMethod selector
+
+    "Created: / 14-11-2014 / 20:17:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomContext methodsFor:'testing'!
+
+isInteractiveContext
+    "Return true, if this generator/refactoring context is interactive,
+     i.e., if it may interact with user (like asking for class name or
+     similar) or not. 
+
+     Generally speaking, only top-level context is interactive an only
+     if generator/refactoring was triggerred from menu.
+    "
+    ^ false
+
+    "Created: / 16-09-2014 / 09:22:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomContext class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomContextTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,113 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomContextTests
+	instanceVariableNames:'context model'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomContextTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomContextTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    model := CustomNamespace new.
+    context := CustomContext new
+        model: model;
+        yourself
+
+    "Modified: / 19-11-2014 / 10:01:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomContextTests methodsFor:'tests'!
+
+test_as_rb_class_class
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: self class name.
+    actualClass := context asRBClass: self class.  
+
+    self deny: expectedClass isMeta.
+    self assert: expectedClass == actualClass.
+    self assert: (actualClass realClass) == (self class).
+
+    "Created: / 19-11-2014 / 10:12:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_as_rb_class_metaclass
+    | expectedMetaclass actualMetaclass class |
+
+    expectedMetaclass := model metaclassNamed: self class name.
+    actualMetaclass := context asRBClass: self class class.  
+    class := context asRBClass: self class.  
+
+    self assert: expectedMetaclass isMeta.
+    self deny: class isMeta.  
+
+    self deny: expectedMetaclass == class.
+    self assert: expectedMetaclass == actualMetaclass.
+    self assert: (expectedMetaclass realClass) == (self class class).
+
+    "Modified: / 19-11-2014 / 10:13:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_copy_with_model
+    | contextCopy newModel |
+
+    newModel := CustomNamespace new.
+    contextCopy := context copyWithModel: newModel.
+    
+    self deny: context == contextCopy.
+    self deny: (context model) == newModel.
+    self assert: (context model) == model.
+    self assert: (contextCopy model) == newModel.
+
+    "Modified: / 25-11-2014 / 19:53:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomDefaultGetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,128 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomDefaultGetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomDefaultGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+    ^ 'Getter methods for default variable value in metaclass'
+
+    "Created: / 30-06-2014 / 11:14:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Getters')
+
+    "Created: / 22-08-2014 / 18:54:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+    ^ 'Getter Method(s) for default variable value'
+
+    "Created: / 30-06-2014 / 11:15:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns getter method source code for default variable value"
+
+    | comment |
+
+    comment := ''.
+
+    userPreferences generateCommentsForGetters ifTrue:[
+        comment := '"default value for the ''%1'' instance variable (automatically generated)"'.
+        comment := comment bindWith: aName.
+    ].
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+            `"comment
+
+            self shouldImplement.
+            ^ nil';
+        replace: '`@methodName' with: (self defaultMethodNameFor: aName) asSymbol;
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Created: / 30-06-2014 / 10:49:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-09-2014 / 22:34:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator methodsFor:'protected'!
+
+methodClass: aClass
+    "Assure that method is generated only for metaclass."
+
+    ^ aClass theMetaclass
+
+    "Created: / 30-06-2014 / 11:11:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDefaultGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomDefaultGetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,96 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomDefaultGetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomDefaultGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomDefaultGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomDefaultGetterMethodsCodeGenerator new
+! !
+
+!CustomDefaultGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_default_getter_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: true.
+
+    expectedSource := 'defaultInstanceVariable
+    "default value for the ''instanceVariable'' instance variable (automatically generated)"
+
+    self shouldImplement.
+    ^ nil'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertClassMethodSource: expectedSource atSelector: #defaultInstanceVariable
+
+    "Created: / 30-06-2014 / 13:31:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-07-2014 / 20:11:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_default_getter_method_generated_without_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: false.
+
+    expectedSource := 'defaultInstanceVariable
+    self shouldImplement.
+    ^ nil'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertClassMethodSource: expectedSource atSelector: #defaultInstanceVariable
+
+    "Created: / 30-06-2014 / 11:31:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-07-2014 / 20:11:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,209 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomDialog
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-UI'
+!
+
+!CustomDialog class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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 simple factory for user dialogs.
+
+    Note: in future, API of this class will be merged into DialogBox and
+    CustomDialog and subclasses will vanish.
+
+    [author:]
+        Jan Vrany <jan.vrany@fit.cvut.cz>
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+    [instance variables:]
+
+    [class variables:]
+
+    [see also:]
+
+"
+! !
+
+!CustomDialog class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CustomDialog
+! !
+
+!CustomDialog methodsFor:'common dialogs'!
+
+requestClassName: label initialAnswer:initial
+
+    | holder |
+
+    holder := ValueHolder with: initial.
+    self addClassNameEntryOn: holder labeled: 'Class' validateBy: nil.
+    self addAbortAndOkButtons.
+    self open ifTrue:[ 
+        ^ holder value
+    ]
+
+    "
+    CustomUserDialog new requestClassName: 'Select class' initialAnswer: 'Array'.
+    "
+
+    "Created: / 10-05-2014 / 15:33:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 15-09-2014 / 16:26:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 21:10:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'construction-adding'!
+
+addAbortAndOkButtons
+    ^ self subclassResponsibility
+
+    "Created: / 15-09-2014 / 16:20:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addButtons
+    self addAbortAndOkButtons
+
+    "Created: / 15-09-2014 / 18:56:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addCheckBoxOn: aValueModel labeled: aString
+    | checkbox |
+
+    checkbox := CheckBox new.
+    checkbox model: aValueModel.
+    checkbox label: aString.
+
+    ^ self addComponent: checkbox labeled: nil.
+
+    "Created: / 15-09-2014 / 18:11:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView
+    "Add given component. Component is automatically stretched to occupy windows' width"
+
+    self subclassResponsibility.
+
+    "Created: / 15-09-2014 / 18:48:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView labeled:labelString
+    "Add a label and some component side-by-side. Returns the component"
+
+    self subclassResponsibility
+
+    "Created: / 15-09-2014 / 15:43:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock
+    | field |
+
+    field := EditField new.
+    field immediateAccept: true.
+    field model: aValueModel.
+
+    ^ self addComponent: field labeled: aString
+
+    "Created: / 15-09-2014 / 15:52:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addSeparator
+    "Add horizontal separator (line)"
+    ^ self addComponent: Separator new
+
+    "Created: / 15-09-2014 / 18:52:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'construction-utilities'!
+
+addClassCategoryEntryOn: aValueModel labeled: aString validateBy: aBlock
+
+    ^ (self addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock)
+        entryCompletionBlock: [:text | DoWhatIMeanSupport classCategoryCompletion: text inEnvironment: Smalltalk ];
+        yourself
+
+    "Created: / 16-09-2014 / 10:13:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addClassNameEntryOn: aValueModel labeled: aString validateBy: aBlock
+
+    ^ (self addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock)
+        entryCompletionBlock: (DoWhatIMeanSupport classNameEntryCompletionBlock);
+        yourself
+
+    "Created: / 15-09-2014 / 15:43:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addSelectorNameEntryOn: aValueModel labeled: aString validateBy: aBlock
+
+    ^ (self addInputFieldOn: aValueModel labeled: aString validatedBy: aBlock)
+        entryCompletionBlock: [:text | DoWhatIMeanSupport selectorCompletion:text inEnvironment:Smalltalk];
+        yourself
+
+    "Created: / 15-10-2014 / 08:44:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'opening'!
+
+open
+    self subclassResponsibility
+
+    "Created: / 15-09-2014 / 16:23:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomDialog methodsFor:'user interaction & notifications'!
+
+information: aString
+
+    self subclassResponsibility
+
+    "Created: / 02-06-2014 / 22:01:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomInspectorTabCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,168 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomInspectorTabCodeGenerator
+	instanceVariableNames:'tabLabel tabPriority'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomInspectorTabCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomInspectorTabCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    ^ 'Generates a new method defining an inspector tab for Inspector2'
+
+    "Modified: / 25-11-2014 / 00:02:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    ^ 'Inspector tab definition'
+
+    "Modified: / 25-11-2014 / 00:02:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomInspectorTabCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext 
+    ^ true
+
+    "Modified: / 24-11-2014 / 23:50:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective 
+    ^ aCustomPerspective isClassPerspective
+
+    "Modified: / 25-11-2014 / 00:01:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomInspectorTabCodeGenerator methodsFor:'accessing'!
+
+tabLabel
+    ^ tabLabel
+!
+
+tabLabel:aString
+    tabLabel := aString.
+!
+
+tabPriority
+    ^ tabPriority
+!
+
+tabPriority:anInteger
+    tabPriority := anInteger.
+! !
+
+!CustomInspectorTabCodeGenerator methodsFor:'executing - private'!
+
+buildInContext:aCustomContext 
+    aCustomContext selectedClasses do:[:cls | 
+        self buildInContext: aCustomContext forClass: cls  
+    ]
+
+    "Modified: / 25-11-2014 / 00:42:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildInContext: aCustomContext forClass: anRBClass
+    | selector |
+
+    selector := String streamContents: [:s | tabLabel asCollectionOfWordsDo:[:w | s nextPutAll: (w select:[:c | c isAlphaNumeric ]) asUppercaseFirst ] ].
+
+    model 
+    compile: 'inspector2Tab',selector,'
+    <inspector2Tab>
+
+    ^ (self newInspector2Tab)
+        label:',tabLabel storeString,';
+        priority:',tabPriority storeString,';
+        "/ view: [ ... ];
+        "/ application: [ ... ];
+        "/ text: [ ... ];
+        yourself   
+    ' 
+    in: anRBClass
+    classified: 'inspecting'.
+
+    "Created: / 25-11-2014 / 00:42:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext
+    "Perform neccessary configuration for given context, such as
+     computing default values for parameters. This may interact with
+     user by means of opening a dialog.
+
+     This method is called only for interactive contexts. When using
+     non interactively, a caller must do the configuration itself by means
+     of accessors."
+
+    "/ To be overridden by subclasses
+
+    | labelHolder priorityHolder |
+
+    tabLabel := 'New Tab Label'.
+    tabPriority := 50.
+
+    labelHolder := (AspectAdaptor forAspect:#tabLabel) subject:self.
+    priorityHolder := (AspectAdaptor forAspect:#tabPriority) subject:self.
+
+    dialog 
+        addInputFieldOn: labelHolder
+        labeled: 'Tab label:'
+        validatedBy: nil.
+
+    dialog 
+        addInputFieldOn: (TypeConverter onNumberValue: priorityHolder minValue: 1 maxValue: 100)
+        labeled: 'Tab priority:'
+        validatedBy: nil.
+
+    dialog addButtons.
+    dialog open.
+
+    "Created: / 25-11-2014 / 00:51:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomIsAbstractCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,121 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomIsAbstractCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomIsAbstractCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomIsAbstractCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Mark class as abstract (by implementing class method #isAbstract)'
+
+    "Created: / 20-03-2014 / 01:31:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Mark class as abstract'
+
+    "Created: / 20-03-2014 / 01:32:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomIsAbstractCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ aCustomContext selectedClasses notEmptyOrNil
+
+    "Created: / 20-03-2014 / 01:34:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    ^ aCustomPerspective isClassPerspective
+
+    "Created: / 20-03-2014 / 01:33:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomIsAbstractCodeGenerator methodsFor:'executing'!
+
+buildInContext:aCustomContext
+    | classes |
+
+    classes := aCustomContext selectedClasses.
+    classes do:[:class |
+        | metaclass className |
+
+        metaclass := class theMetaclass.
+        className := class theNonMetaclass name.
+
+        (metaclass includesSelector: #isAbstract) ifFalse:[  
+            self compile: ('isAbstract
+    ^ self == %1' bindWith: className) forClass: metaclass inCategory: 'testing'
+        ].   
+    ]
+
+    "Created: / 16-09-2014 / 07:20:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 17:23:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomIsAbstractCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,135 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomIsAbstractCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomIsAbstractCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomIsAbstractCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomIsAbstractCodeGenerator new
+! !
+
+!CustomIsAbstractCodeGeneratorTests methodsFor:'tests'!
+
+test_available_in_context
+
+    self deny: (generatorOrRefactoring class availableInContext:context).
+
+    context selectedClasses: (Array with: self class).
+
+    self assert: (generatorOrRefactoring class availableInContext:context).
+
+    "Modified (format): / 15-11-2014 / 15:51:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_class
+    
+    self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective)
+
+    "Modified: / 15-11-2014 / 15:52:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_method_exists
+    | expectedSource metaclass class |
+
+    metaclass := model createClass
+        name: #DummyClass01;
+        compile;
+        theMetaclass.
+
+    metaclass compile: 'isAbstract ^ false'.
+
+    expectedSource := 'isAbstract ^ false'.
+
+    context selectedClasses: (Array with: metaclass).
+    generatorOrRefactoring executeInContext: context.  
+
+    class := Smalltalk at: #DummyClass01.
+    self assertClassMethodSource:expectedSource atSelector:#isAbstract forClass:class
+
+    "Created: / 16-11-2014 / 17:25:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_method_generated
+    |expectedSource|
+
+    expectedSource := 'isAbstract
+    ^ self == DummyClassForGeneratorTestCase'.
+
+    self executeGeneratorInContext:#classWithInstanceVariable. 
+
+    self assertClassMethodSource:expectedSource atSelector:#isAbstract
+
+    "Created: / 15-11-2014 / 15:53:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 15-11-2014 / 19:32:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_method_generated_for_metaclass
+    | expectedSource metaclass class |
+
+    metaclass := model createClass
+        name: #DummyClass01;
+        compile;
+        theMetaclass.
+
+    expectedSource := 'isAbstract
+    ^ self == DummyClass01'.
+
+    context selectedClasses: (Array with: metaclass).
+    generatorOrRefactoring executeInContext: context.  
+
+    class := Smalltalk at: #DummyClass01.
+    self assertClassMethodSource:expectedSource atSelector:#isAbstract forClass:class
+
+    "Created: / 16-11-2014 / 17:17:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,99 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomSimpleSetterMethodsCodeGenerator subclass:#CustomJavaScriptSimpleSetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomJavaScriptSimpleSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Same purpose like superclass, but for STX JavaScript language.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGenerator class methodsFor:'queries'!
+
+availableForProgrammingLanguages
+
+    ^ {STXJavaScriptLanguage instance}
+
+    "Created: / 31-01-2015 / 18:16:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns simple setter for given STX JavaScript class and variable name."
+
+    | methodName comment argName |
+
+    methodName := aName.
+    argName := self argNameForMethodName: methodName.  
+    comment := ''.
+
+    userPreferences generateCommentsForSetters ifTrue:[
+        | varType |
+
+        varType := self varTypeOf: aName class: aClass. 
+        comment := '
+    // set the value of the %1 variable ''%2'' (automatically generated)'.
+        comment := comment bindWith: varType with: aName.
+    ].
+
+    ^ methodName, '(', argName, ') {', comment, '
+    ', aName, ' = ', argName, ';
+}'.
+
+    "Created: / 31-01-2015 / 18:15:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,133 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests
+	instanceVariableNames:'javaScriptClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomJavaScriptSimpleSetterMethodsCodeGenerator new
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests methodsFor:'initialization & release'!
+
+setUp
+    | classDefinition |
+
+    super setUp.
+
+    classDefinition := 'public class DummyJavaStriptClass01 extends Object {
+    var instVar01;
+}'.
+
+    Class withoutUpdatingChangesDo: [   
+        JavaScriptCompiler evaluate: classDefinition notifying: nil compile: nil
+    ].
+
+    javaScriptClass := Smalltalk at: #DummyJavaStriptClass01.
+
+    "Modified: / 01-02-2015 / 16:22:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    Class withoutUpdatingChangesDo: [   
+        javaScriptClass removeFromSystem
+    ].
+    "super tearDown."
+    "Call of undoing changes produces error relevant
+    to parsing JavaScript source code as Smalltalk code."
+    "changeManager undoChanges."
+    mock unmockAll
+
+    "Modified: / 01-02-2015 / 16:21:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_simple_setter_generated_with_comment
+    | expectedSource |
+
+    userPreferences generateComments: true.
+
+    context selectedClasses: {javaScriptClass}.  
+
+    expectedSource := 'instVar01(something) {
+    // set the value of the instance variable ''instVar01'' (automatically generated)
+    instVar01 = something;
+}'.
+
+    generatorOrRefactoring executeInContext: context.
+
+    self assertMethodSource: expectedSource atSelector: #'instVar01:' forClass: javaScriptClass
+
+    "Created: / 01-02-2015 / 16:24:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_simple_setter_generated_without_comment
+    | expectedSource |
+
+    userPreferences generateComments: false.
+
+    context selectedClasses: {javaScriptClass}.  
+
+    expectedSource := 'instVar01(something) {
+    instVar01 = something;
+}'.
+
+    generatorOrRefactoring executeInContext: context.
+
+    self assertMethodSource: expectedSource atSelector: #'instVar01:' forClass: javaScriptClass
+
+    "Created: / 01-02-2015 / 16:26:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,138 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomJavaSimpleSetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomJavaSimpleSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomJavaSimpleSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Generates setter methods for instance variables of Java Class'
+
+    "Created: / 01-02-2015 / 20:42:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Setter Method(s)'
+
+    "Created: / 01-02-2015 / 20:43:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaSimpleSetterMethodsCodeGenerator class methodsFor:'queries'!
+
+availableForProgrammingLanguages
+    "Returns list of programming language instances for which this generator / refactoring works.
+    (SmalltalkLanguage instance, JavaLanguage instance, GroovyLanguage instance, etc.)
+
+     See also availableForProgrammingLanguagesInContext:withPerspective:"
+
+    ^ {JavaLanguage instance}
+
+    "Created: / 01-02-2015 / 20:44:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInContext: aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ aCustomContext selectedClasses notEmptyOrNil
+
+    "Created: / 01-02-2015 / 20:40:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective: aCustomPerspective
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    ^ aCustomPerspective isClassPerspective
+
+    "Created: / 01-02-2015 / 20:41:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomJavaSimpleSetterMethodsCodeGenerator methodsFor:'executing - private'!
+
+buildInContext: aCustomContext
+    "Prototype generator for Java language - proper way should be usage of some Java parser"
+
+    self warn: 'Experimenatal generator, may not work as expected.'.  
+
+    aCustomContext selectedClasses do: [ :class |
+        class instanceVariableNames do: [ :varName |
+            | setter type newDefinition endOfClass |
+
+            type := (class realClass typeOfField: varName) asString.
+            setter := '
+    public ', type, ' ', varName, '(', type, ' ', varName, ') {
+        this.', varName, ' = ', varName, ';
+    }
+'.
+            newDefinition := class realClass definition.
+            endOfClass := newDefinition lastIndexOf: $}.
+            newDefinition := (newDefinition copyTo: endOfClass - 1), setter, (newDefinition copyFrom: endOfClass).
+            JavaCompiler compile: newDefinition
+        ]
+    ]
+
+    "Created: / 01-02-2015 / 17:58:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 02-02-2015 / 22:20:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomLazyInitializationAccessMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomLazyInitializationAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Access Method(s) with Lazy Initialization in Getter for selected instance variables'
+
+    "Modified: / 08-07-2014 / 18:10:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Access Method(s) with Lazy Initialization in Getter'
+
+    "Modified: / 08-07-2014 / 18:10:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Creates access methods with lazy initialization in getter for given context"
+
+    self executeSubGeneratorOrRefactoringClasses:(Array 
+                  with:CustomLazyInitializationGetterMethodsCodeGenerator
+                  with:CustomChangeNotificationSetterMethodsCodeGenerator)
+          inContext:aCustomContext
+
+    "Modified: / 08-07-2014 / 18:37:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationAccessMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,134 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomLazyInitializationAccessMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomLazyInitializationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomLazyInitializationAccessMethodsCodeGenerator new
+! !
+
+!CustomLazyInitializationAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_lazy_initialization_access_methods_generated_with_comments
+    | expectedGetterSource expectedSetterSource expectedDefaultSource |
+
+    userPreferences
+        generateCommentsForGetters: true;
+        generateCommentsForSetters: true.
+
+    expectedGetterSource := 'instanceVariable
+    "return the instance instance variable ''instanceVariable'' with lazy instance creation (automatically generated)"
+
+    instanceVariable isNil ifTrue:[
+        instanceVariable := self class defaultInstanceVariable.
+    ].
+    ^ instanceVariable'.
+
+    expectedSetterSource := 'instanceVariable:something 
+    "set the value of the instance variable ''instanceVariable'' and send a change notification (automatically generated)"
+
+    (instanceVariable ~~ something) ifTrue:[
+        instanceVariable := something.
+        self changed:#instanceVariable.
+    ].'.
+
+    expectedDefaultSource := 'defaultInstanceVariable
+    "default value for the ''instanceVariable'' instance variable (automatically generated)"
+
+    self shouldImplement.
+    ^ nil'.
+
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:.
+    self assertClassMethodSource: expectedDefaultSource atSelector: #defaultInstanceVariable
+
+    "Created: / 08-07-2014 / 18:43:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-07-2014 / 20:11:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_lazy_initialization_access_methods_generated_without_comments
+    | expectedGetterSource expectedSetterSource expectedDefaultSource |
+
+    userPreferences
+        generateCommentsForGetters: false;
+        generateCommentsForSetters: false.
+
+    expectedGetterSource := 'instanceVariable
+    instanceVariable isNil ifTrue:[
+        instanceVariable := self class defaultInstanceVariable.
+    ].
+    ^ instanceVariable'.
+
+    expectedSetterSource := 'instanceVariable:something 
+    (instanceVariable ~~ something) ifTrue:[
+        instanceVariable := something.
+        self changed:#instanceVariable.
+    ].'.
+
+    expectedDefaultSource := 'defaultInstanceVariable
+    self shouldImplement.
+    ^ nil'.
+
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:.
+    self assertClassMethodSource: expectedDefaultSource atSelector: #defaultInstanceVariable
+
+    "Created: / 08-07-2014 / 19:37:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-07-2014 / 20:11:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,136 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomLazyInitializationGetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomLazyInitializationGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Getter methods with Lazy Initialization in Getter for selected instance variables'
+
+    "Created: / 29-06-2014 / 19:12:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Getters')
+
+    "Created: / 22-08-2014 / 18:56:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Getter Method(s) with Lazy Initialization'
+
+    "Created: / 29-06-2014 / 19:16:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 06-07-2014 / 23:14:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns getter with lazy initialization method source code for given class and variable name"
+
+    | methodName comment |
+
+    methodName := self methodNameFor: aName.
+    comment := ''.
+
+    userPreferences generateCommentsForGetters ifTrue:[
+        | varType |
+
+        varType := self varTypeOf: aName class: aClass. 
+        comment := '"return the %1 instance variable ''%2'' with lazy instance creation (automatically generated)"'.
+        comment := comment bindWith: varType with: aName.
+    ].
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+            `"comment
+
+            `variableName isNil ifTrue:[
+                `variableName := self class `@defaultMethodName.
+            ].
+            ^ `variableName';
+        replace: '`@methodName' with: methodName asSymbol;
+        replace: '`@defaultMethodName' with: (self defaultMethodNameFor: aName) asSymbol;
+        replace: '`variableName' with: aName asString;
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Created: / 24-06-2014 / 23:24:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-09-2014 / 22:35:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    | generator |
+
+    generator := CustomDefaultGetterMethodsCodeGenerator subGeneratorOrRefactoringOf:self.
+    generator executeInContext: aCustomContext.
+
+    super buildInContext: aCustomContext
+
+    "Created: / 30-06-2014 / 18:00:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLazyInitializationGetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,121 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomLazyInitializationGetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomLazyInitializationGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomLazyInitializationGetterMethodsCodeGenerator new
+! !
+
+!CustomLazyInitializationGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_lazy_initialization_getter_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: true.
+
+    expectedSource := 'instanceVariable
+    "return the instance instance variable ''instanceVariable'' with lazy instance creation (automatically generated)"
+
+    instanceVariable isNil ifTrue:[
+        instanceVariable := self class defaultInstanceVariable.
+    ].
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 30-06-2014 / 18:03:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_lazy_initialization_getter_method_generated_with_default_method
+    | expectedGetterSource expectedDefaultSource |
+
+    userPreferences generateCommentsForGetters: false.
+
+    expectedGetterSource := 'instanceVariable
+    instanceVariable isNil ifTrue:[
+        instanceVariable := self class defaultInstanceVariable.
+    ].
+    ^ instanceVariable'.
+
+    expectedDefaultSource := 'defaultInstanceVariable
+    self shouldImplement.
+    ^ nil'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertClassMethodSource: expectedDefaultSource atSelector: #defaultInstanceVariable
+
+    "Created: / 30-06-2014 / 18:06:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-07-2014 / 20:11:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_lazy_initialization_getter_method_generated_without_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: false.
+
+    expectedSource := 'instanceVariable
+    instanceVariable isNil ifTrue:[
+        instanceVariable := self class defaultInstanceVariable.
+    ].
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 30-06-2014 / 10:37:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLocalChangeManager.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,117 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomChangeManager subclass:#CustomLocalChangeManager
+	instanceVariableNames:'executedChanges'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomLocalChangeManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Unlike CustomBrowserChangeManager this implementation should not affect
+    global Browser changes collector, Browser menus and the change file (st.chg).
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz> 
+
+"
+! !
+
+!CustomLocalChangeManager class methodsFor:'instance creation'!
+
+new
+
+    ^ self basicNew initialize
+
+    "Created: / 31-05-2014 / 19:34:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManager methodsFor:'initialization'!
+
+initialize
+
+    executedChanges := OrderedCollection new.
+
+    "Created: / 31-05-2014 / 19:31:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManager methodsFor:'performing-changes'!
+
+performChange: aRefactoringChange
+    "Applies code change (add/change/remove class/method ...) to the system"
+
+    Class withoutUpdatingChangesDo:[ 
+        executedChanges add: aRefactoringChange execute
+    ]
+
+    "Modified: / 30-11-2014 / 18:21:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+undoChanges
+    "undo all changes made by performChange: method"
+
+    Class withoutUpdatingChangesDo:[ 
+        executedChanges reversed do: [ :change | 
+            change execute
+        ]
+    ].
+
+    executedChanges removeAll
+
+    "Created: / 19-10-2014 / 14:59:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-11-2014 / 15:40:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManager class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomLocalChangeManagerTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,124 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomLocalChangeManagerTests
+	instanceVariableNames:'changeManager'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomLocalChangeManagerTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomLocalChangeManagerTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    changeManager := CustomLocalChangeManager new.
+
+    "Modified: / 30-11-2014 / 17:32:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+    super tearDown.
+
+    (Smalltalk at: #DummyClass01) notNil ifTrue: [ 
+        Class withoutUpdatingChangesDo: [ 
+            (Smalltalk at: #DummyClass01) removeFromSystem
+        ]
+    ]
+
+    "Created: / 30-11-2014 / 17:40:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManagerTests methodsFor:'private'!
+
+lastChangeInRefactoryChangeManagerAt: aSelector
+
+    ^ [ 
+        RefactoryChangeManager instance perform: aSelector
+    ] on: Collection emptyCollectionSignal do: [ 
+        nil
+    ]
+
+    "Created: / 30-11-2014 / 18:09:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomLocalChangeManagerTests methodsFor:'tests'!
+
+test_perform_change_with_nothing_external_modified
+    | expectedUndo expectedRedo actualUndo actualRedo expectedChangeContents actualChangeContents |
+
+    expectedUndo := self lastChangeInRefactoryChangeManagerAt: #undoChange.
+    expectedRedo := self lastChangeInRefactoryChangeManagerAt: #redoChange.
+    expectedChangeContents := ObjectMemory nameForChanges asFilename contents.
+
+    self assert: (Smalltalk at: #DummyClass01) isNil.
+
+    changeManager performChange: (AddClassChange definition: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''' 
+    ').
+
+    self assert: (Smalltalk at: #DummyClass01) notNil.
+
+    changeManager undoChanges.
+
+    self assert: (Smalltalk at: #DummyClass01) isNil.
+
+    actualUndo := self lastChangeInRefactoryChangeManagerAt: #undoChange.
+    actualRedo := self lastChangeInRefactoryChangeManagerAt: #redoChange.
+    actualChangeContents := ObjectMemory nameForChanges asFilename contents.
+
+    self assert: expectedRedo == actualRedo.
+    self assert: expectedUndo == actualUndo.
+    self assert: expectedChangeContents = actualChangeContents.
+
+    "Modified: / 30-11-2014 / 18:20:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomManager.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,229 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomManager
+	instanceVariableNames:'generatorsOrRefactoringsProvider'
+	classVariableNames:'Current'
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomManager class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Starting point for accessing generators and refactoring classes.
+    Class method 'current' provides current system setup.
+    Instance methods basically returns or iterates some subset of generators or refactoring classes.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomManager class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    Current := self new
+
+    "Modified: / 25-01-2014 / 14:54:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 12:12:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!CustomManager class methodsFor:'accessing'!
+
+current
+    "Returns my global instance within system"
+
+    ^ Current
+
+    "Created: / 25-01-2014 / 14:55:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 12:12:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager methodsFor:'accessing'!
+
+generatorsAndRefactorings
+    "Returns all generators and refactorings from generatorsOrRefactoringsProvider"
+
+    ^ OrderedCollection streamContents:[ :s |
+        self generatorsAndRefactoringsDo: [ :each |
+            s nextPut: each .
+        ]  
+    ]
+
+    "Created: / 25-01-2014 / 15:02:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 11:55:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForContext: aCustomContext
+    "Returns generators and refactorings available for given context"
+
+    ^ OrderedCollection streamContents:[ :s |
+        self generatorsAndRefactoringsForContext: aCustomContext do: [ :each |
+            s nextPut: each .
+        ]  
+    ]
+
+    "Created: / 25-01-2014 / 15:06:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 11:57:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForPerspective: aCustomPerspective
+    "Returns generators and refactorings available for given perspective"
+
+    ^ OrderedCollection streamContents:[ :s |
+        self generatorsAndRefactoringsForPerspective: aCustomPerspective do: [ :each |
+            s nextPut: each .
+        ]  
+    ]
+
+    "Created: / 26-01-2014 / 13:18:38 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 26-01-2014 / 23:35:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 11:57:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsSelect: aBlock
+    "Returns generators and refactorings classes for which the block returns true"
+
+    ^ OrderedCollection streamContents:[ :stream |
+        self generatorsAndRefactoringsDo: [ :each |
+            (aBlock value: each) ifTrue: [ 
+                stream nextPut: each
+            ]
+        ]  
+    ]
+
+    "Created: / 28-12-2014 / 13:03:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsOrRefactoringsProvider
+    "Returns an iterator (implements generatorsAndRefactoringsDo:) from where generators or refactorings will be taken."
+
+    ^ generatorsOrRefactoringsProvider
+
+    "Modified (comment): / 28-12-2014 / 12:05:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsOrRefactoringsProvider: aProvider
+    "see generatorsOrRefactoringsProvider"
+
+    generatorsOrRefactoringsProvider := aProvider
+
+    "Modified (comment): / 28-12-2014 / 12:06:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager methodsFor:'enumerating'!
+
+generatorsAndRefactoringsDo: aBlock
+    "Evaluates a block on all installed generator and refactoring classes.
+     NOTE: the block gets the generator/refactoring class. not an instance."
+
+    generatorsOrRefactoringsProvider generatorsAndRefactoringsDo: [ :each |
+        each isAbstract ifFalse:[
+            aBlock value: each 
+        ].
+    ]
+
+    "Created: / 25-01-2014 / 15:01:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 26-01-2014 / 13:17:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 28-12-2014 / 11:52:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForContext: aCustomContext do: aBlock
+    "Evaluates a block on generator and refactoring classes available for given context"
+
+    self generatorsAndRefactoringsDo: [ :each |
+        (each availableInContext: aCustomContext) ifTrue:[ 
+            aBlock value: each 
+        ].
+    ]
+
+    "Created: / 25-01-2014 / 15:03:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 12:08:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorsAndRefactoringsForPerspective: aCustomPerspective do: aBlock
+    "Evaluates a block on generator and refactoring classes available for given perspective"
+
+    self generatorsAndRefactoringsDo: [ :each |
+        (each availableInPerspective: aCustomPerspective) ifTrue:[ 
+            aBlock value: each 
+        ].
+    ]
+
+    "Created: / 26-01-2014 / 13:18:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 12:08:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    generatorsOrRefactoringsProvider := CustomCodeGeneratorOrRefactoring
+
+    "Modified: / 28-12-2014 / 11:53:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManager class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
+
+CustomManager initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomManagerTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,303 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomManagerTests
+	instanceVariableNames:'mock provider manager generatorClassMock'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomManagerTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomManagerTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    mock := CustomMock new.
+    provider := mock mockOf: OrderedCollection.
+    provider compileMockMethod: 'generatorsAndRefactoringsDo: aBlock
+        self do: aBlock'.
+
+    manager := CustomManager new.
+    manager generatorsOrRefactoringsProvider: provider.
+
+    generatorClassMock := mock mockClassOf: Object.
+    mock createMockGetters: generatorClassMock forSelectors:
+        {'label'. 'isAbstract'. 'availableInContext:'. 'availableInPerspective:'}.
+
+    "Modified: / 28-12-2014 / 15:34:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    mock unmockAll.
+    
+    super tearDown.
+
+    "Modified: / 28-12-2014 / 13:15:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManagerTests methodsFor:'private'!
+
+addGenerator: aLabel
+    "Creates initialized code generator mock and adds it to managers generators"
+    | generator |
+
+    generator := generatorClassMock new
+        objectAttributeAt: #isAbstract put: false;
+        objectAttributeAt: #label put: aLabel;
+        objectAttributeAt: #availableInContext: put: true;
+        objectAttributeAt: #availableInPerspective: put: true;
+        yourself.
+
+    manager generatorsOrRefactoringsProvider add: generator.
+
+    ^ generator
+
+    "Created: / 28-12-2014 / 14:12:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 28-12-2014 / 15:36:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+collectionOfLabels: aCollection
+    "Returns collection of labels from given collection"
+
+    ^ OrderedCollection streamContents: [ :stream |
+        aCollection do: [ :each | 
+            stream nextPut: each label
+        ]
+    ]
+
+    "Created: / 28-12-2014 / 14:23:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManagerTests methodsFor:'tests'!
+
+test_current
+    
+    self assert: manager class current notNil
+
+    "Modified: / 28-12-2014 / 13:17:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings
+    | expectedGenerators actualGenerators |
+
+    expectedGenerators := OrderedCollection with: 'Generator_01' with: 'Generator_02'.
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    actualGenerators := self collectionOfLabels: manager generatorsAndRefactorings.
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified: / 28-12-2014 / 14:23:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_do
+    | expectedGenerators actualGenerators |
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    expectedGenerators := OrderedCollection with: provider first 
+                            with: provider last.
+
+    actualGenerators := OrderedCollection streamContents: [ :stream |
+        manager generatorsAndRefactoringsDo: [ :generator |  
+            stream nextPut: generator
+        ].
+    ].                 
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified: / 28-12-2014 / 18:04:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_context
+    | expectedGenerators actualGenerators |
+
+    expectedGenerators := OrderedCollection with: 'Generator_02'.
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    provider first objectAttributeAt: #availableInContext: put: false.    
+
+    actualGenerators := self collectionOfLabels: (manager 
+                            generatorsAndRefactoringsForContext: nil).
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified: / 28-12-2014 / 15:38:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_context_do
+    | expectedGenerators actualGenerators |
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    expectedGenerators := OrderedCollection with: provider first. 
+    provider last objectAttributeAt: #availableInContext: put: false.
+
+    actualGenerators := OrderedCollection streamContents: [ :stream |
+        manager generatorsAndRefactoringsForContext: nil do: [ :generator |  
+            stream nextPut: generator
+        ].
+    ].                 
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified: / 28-12-2014 / 18:08:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_perspective    
+    | expectedGenerators actualGenerators |
+
+    expectedGenerators := OrderedCollection with: 'Generator_01'.
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    provider second objectAttributeAt: #availableInPerspective: put: false.    
+
+    actualGenerators := self collectionOfLabels: (manager 
+                            generatorsAndRefactoringsForPerspective: nil).
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified: / 28-12-2014 / 17:07:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_for_perspective_do
+    | expectedGenerators actualGenerators |
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    expectedGenerators := OrderedCollection with: provider first. 
+    provider last objectAttributeAt: #availableInPerspective: put: false.
+
+    actualGenerators := OrderedCollection streamContents: [ :stream |
+        manager generatorsAndRefactoringsForPerspective: nil do: [ :generator |  
+            stream nextPut: generator
+        ].
+    ].                 
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified: / 28-12-2014 / 18:08:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_select_01    
+    | expectedGenerators actualGenerators |
+
+    expectedGenerators := OrderedCollection with: 'Generator_01'.
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    provider second objectAttributeAt: #availableInPerspective: put: false.    
+
+    actualGenerators := self collectionOfLabels: (manager 
+                            generatorsAndRefactoringsSelect: [ :generator | 
+                                generator availableInPerspective: nil
+                            ]).
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Modified (comment): / 28-12-2014 / 17:54:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_select_02    
+    | expectedGenerators actualGenerators |
+
+    expectedGenerators := OrderedCollection new.
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    provider second objectAttributeAt: #availableInPerspective: put: false.    
+
+    actualGenerators := self collectionOfLabels: (manager 
+                            generatorsAndRefactoringsSelect: [ :generator | 
+                                false
+                            ]).
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Created: / 28-12-2014 / 17:55:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generators_and_refactorings_select_03    
+    | expectedGenerators actualGenerators |
+
+    expectedGenerators := OrderedCollection with: 'Generator_01' with: 'Generator_02'.
+
+    self addGenerator: 'Generator_01';
+        addGenerator: 'Generator_02'.
+
+    provider second objectAttributeAt: #availableInPerspective: put: false.    
+
+    actualGenerators := self collectionOfLabels: (manager 
+                            generatorsAndRefactoringsSelect: [ :generator | 
+                                true
+                            ]).
+
+    self assert: expectedGenerators = actualGenerators
+
+    "Created: / 28-12-2014 / 17:55:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomManagerTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMenuBuilder.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,380 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomMenuBuilder
+	instanceVariableNames:'perspective menu submenuLabel afterMenuItemLabelled
+		generatorOrRefactoringFilter resources navigationState manager
+		errorPrinter'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-UI'
+!
+
+!CustomMenuBuilder class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Injects menu item with submenu filled with generators or refactorings to the given menu.
+    Basically helps to extend system browser (NewSystemBrowser) context menu (for example
+    the menu which pop-ups after right-click on the class list).
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomMenuBuilder class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!CustomMenuBuilder class methodsFor:'building'!
+
+buildMenuForContext:context filter: filter
+    ^ self new buildMenuForContext:context filter: filter
+
+    "Created: / 26-08-2014 / 10:12:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder methodsFor:'accessing'!
+
+afterMenuItemLabelled
+    "Returns menu item label after which will be placed 
+     new menu item with generators or refactorings"
+    
+    ^ afterMenuItemLabelled
+
+    "Modified (comment): / 28-12-2014 / 23:22:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+afterMenuItemLabelled:aLabel 
+    "see afterMenuItemLabeled"
+    
+    afterMenuItemLabelled := aLabel
+
+    "Modified (comment): / 28-12-2014 / 23:20:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+errorPrinter
+    "Returns printer (like Transcript) which should print/show errors while menu building.
+    Better to print errors silently than destroy IDE functionality with recurring errors."
+
+    ^ errorPrinter
+
+    "Modified (comment): / 01-02-2015 / 19:38:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+errorPrinter: aPrinter
+    "see errorPrinter"
+
+    errorPrinter := aPrinter.
+
+    "Modified (comment): / 01-02-2015 / 19:38:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorOrRefactoringFilter
+    "Returns one argument block which is used to filter generators or refactorings"
+
+    ^ generatorOrRefactoringFilter
+
+    "Modified (comment): / 28-12-2014 / 23:23:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generatorOrRefactoringFilter: aOneArgBlock
+    "see generatorOrRefactoringFilter"
+
+    generatorOrRefactoringFilter := aOneArgBlock
+
+    "Modified (comment): / 28-12-2014 / 23:25:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+groupsSortBlock
+    "Returns a block used to sort generator or refactoring groups"
+
+    ^ [ :a :b | 
+        a size = b size ifTrue: [ 
+            | i | 
+
+            i := 1.
+
+            [ i < a size and: [ (a at:i) = (b at:i) ] ] whileTrue: [
+                i := i + 1 
+            ].
+
+            (a at:i) < (b at:i)
+        ] ifFalse: [
+            a size < b size
+        ]
+    ]
+
+    "Created: / 28-12-2014 / 20:56:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+manager
+    "Returns generator or refactoring manager which is used to access them.
+    See CustomManager for more details."
+
+    ^ manager
+
+    "Modified (comment): / 28-12-2014 / 23:26:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+manager: aManager
+    "see manager"
+
+    manager := aManager
+
+    "Modified (comment): / 28-12-2014 / 23:27:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menu
+    "Returns menu (instance of class Menu) in which is created new
+    menu item with submenu filled with generators or refactorings"
+
+    ^ menu
+
+    "Modified (comment): / 28-12-2014 / 23:28:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menu: aMenu
+    "see menu"
+
+    menu := aMenu
+
+    "Modified (comment): / 28-12-2014 / 23:28:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+navigationState
+    "see Tools::NavigationState"
+
+    ^ navigationState
+
+    "Modified (comment): / 28-12-2014 / 23:29:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+navigationState: aNavigationState
+    "see Tools::NavigationState"
+
+    navigationState := aNavigationState
+
+    "Created: / 28-12-2014 / 10:09:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 28-12-2014 / 23:29:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+perspective
+    "see CustomPerspective"
+
+    ^ perspective
+
+    "Modified (comment): / 28-12-2014 / 23:30:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+perspective: aCustomPerspective
+    "see CustomPerspective"
+
+    perspective := aCustomPerspective
+
+    "Modified (comment): / 28-12-2014 / 23:30:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+resources
+    "Used to translate menu labels (resources string:)"
+
+    ^ resources
+
+    "Modified (comment): / 28-12-2014 / 23:31:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+resources: someResources
+    "see resources"
+
+    resources := someResources
+
+    "Modified (comment): / 28-12-2014 / 23:32:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+submenuLabel
+    "Returns label of menu item which contains submenu with generators or refactorings"
+
+    ^ submenuLabel
+
+    "Modified (comment): / 28-12-2014 / 23:33:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+submenuLabel: aLabel
+    "see submenuLabel"
+
+    submenuLabel := aLabel
+
+    "Modified (comment): / 28-12-2014 / 23:33:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder methodsFor:'building'!
+
+buildMenu
+    | item context submenuChannel |
+
+    (menu isNil or: [ perspective isNil ]) ifTrue: [ 
+        self error: 'Attributes named menu and perspective are required.'
+    ].
+
+    item := MenuItem label: (resources string: submenuLabel).
+    context := SmallSense::CustomBrowserContext 
+                    perspective: perspective
+                    state: navigationState.
+
+    submenuChannel := [ self buildMenuForContext: context filter: generatorOrRefactoringFilter ].
+    "Do not show empty context menu"
+    submenuChannel value hasItems ifTrue: [ 
+        item submenuChannel: submenuChannel.
+        self 
+            placeMenuItem: item 
+            afterMenuItemLabeled: afterMenuItemLabelled 
+            forMenu: menu 
+    ]
+
+    "Created: / 27-12-2014 / 17:20:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:57:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:07:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildMenuForContext: context filter: filter 
+    | submenu generatorsAndRefactorings groups groupsMap |
+
+    submenu := Menu new.
+    generatorsAndRefactorings := manager generatorsAndRefactoringsSelect: [ :generatorOrRefactoring |
+        [ (generatorOrRefactoring availableInPerspective: context perspective)
+            and: [ filter value: generatorOrRefactoring ]
+            and: [ generatorOrRefactoring availableForProgrammingLanguagesInContext: context ]
+            and: [ generatorOrRefactoring label notNil ]
+        ] on: Error do: [ :error |
+            errorPrinter showCR: 'An error occured when selecting code generators/refactorings.'.
+            errorPrinter showCR: 'Class: ', generatorOrRefactoring name, ' Error: ', error asString.  
+            false
+        ].
+    ].
+
+    "/ Now, group them by group.
+    groupsMap := Dictionary new.
+    groups := OrderedCollection new.
+    generatorsAndRefactorings do:[:each |
+        | group |
+
+        group := each group.
+        (groupsMap includesKey: group) ifTrue:[ 
+            (groupsMap at: group) add: each.
+        ] ifFalse:[ 
+            groupsMap at: group put: (OrderedCollection with: each).
+            groups add: group.
+        ].
+    ].
+
+    groups sort: self groupsSortBlock.
+
+    groups do:[:name |  
+        | items |
+
+        items := groupsMap at: name.
+        items sort:[ :a :b | a label < b label ].
+        items do:[:each | 
+            | item |
+
+            item := MenuItem label: (resources string: each label)
+                    itemValue:[ each executeInContextWithWaitCursor: context ].
+            item enabled:[ each availableInContext: context ].
+            submenu addItem:item.
+        ].
+    ] separatedBy:[ 
+        submenu addSeparator.
+    ].
+
+    ^ submenu
+
+    "Created: / 26-08-2014 / 10:13:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-02-2015 / 20:18:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+placeMenuItem: aMenuItem afterMenuItemLabeled: aLabel forMenu: aMenu
+    "Places a menu item after another menu item identified by label
+    within given menu."    
+    | index |
+
+    index := aMenu indexOfMenuItemForWhich:[:each | each label = aLabel ].
+    index ~~ 0 ifTrue:[
+        "Labeled item found"
+        aMenu addItem: aMenuItem beforeIndex: index + 1.
+    ] ifFalse:[
+        aMenu addItem: aMenuItem.
+    ].
+
+    "Created: / 27-12-2014 / 18:45:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    menu := Menu new.
+    submenuLabel := 'Unknown menu label'.
+    generatorOrRefactoringFilter := [ :generatorOrRefactoring | true ].
+    resources := self class classResources.
+    manager := SmallSense::CustomManager current.
+    errorPrinter := Transcript
+
+    "Modified: / 01-02-2015 / 19:31:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:07:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilder class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMenuBuilderTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,601 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomMenuBuilderTests
+	instanceVariableNames:'builder menu provider manager mock generatorClassMock resources'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-UI-Tests'
+!
+
+!CustomMenuBuilderTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomMenuBuilderTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    menu := Menu labels: 'Label_01
+Label_02
+Label_03' values: nil.
+
+    mock := CustomMock new.
+
+    provider := mock mockOf: OrderedCollection.
+    provider compileMockMethod: 'generatorsAndRefactoringsDo: aBlock
+        self do: aBlock'.  
+
+    manager := CustomManager new.
+    manager generatorsOrRefactoringsProvider: provider.
+
+    builder := CustomMenuBuilder new.
+    builder manager: manager.
+
+    generatorClassMock := mock mockClassOf: Object.
+    mock createMockGetters: generatorClassMock forSelectors: {
+        'label'. 'group'. 'name'. 'isAbstract'. 'availableInContext:'. 
+        'availableInPerspective:'. 'availableForProgrammingLanguagesInContext:'
+    }.
+
+    resources := mock mockOf: Object.
+    resources compileMockMethod: 'string:aString ^ ''Translated '', aString'.
+
+    "Modified: / 01-02-2015 / 20:00:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    mock unmockAll.
+    
+    super tearDown.
+
+    "Modified: / 28-12-2014 / 22:02:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilderTests methodsFor:'private'!
+
+addGenerator: aLabel group: aGroup
+    "Creates initialized code generator mock and adds it to managers generators"
+    | generator |
+
+    generator := generatorClassMock new
+        objectAttributeAt: #isAbstract put: false;
+        objectAttributeAt: #label put: aLabel;
+        objectAttributeAt: #name put: 'Unknown class name';
+        objectAttributeAt: #group put: aGroup;
+        objectAttributeAt: #availableInContext: put: true;
+        objectAttributeAt: #availableInPerspective: put: true;
+        objectAttributeAt: #availableForProgrammingLanguagesInContext: put: true;
+        yourself.
+
+    manager generatorsOrRefactoringsProvider add: generator.
+
+    ^ generator
+
+    "Created: / 28-12-2014 / 22:10:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 01-02-2015 / 20:01:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menuItemLabels
+    "Helper which returns labels from menu item as collection as string.
+    We are comparing labels, because menu items are not comparable - 
+    MenuItem label: 'Label' not equals MenuItem label: 'Label'"
+
+    ^ (OrderedCollection streamContents: [ :stream |
+        menu itemsDo: [ :item |
+            stream nextPut: item label.
+            item submenuChannel notNil ifTrue: [ 
+                stream nextPut: (OrderedCollection streamContents: [ :innerStream |
+                    item submenuChannel value itemsDo: [ :innerItem |
+                        innerStream nextPut: innerItem label
+                    ]
+                ]) asArray
+            ]
+        ]
+    ]) asArray
+
+    "Created: / 28-12-2014 / 10:41:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 28-12-2014 / 23:17:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilderTests methodsFor:'tests'!
+
+test_build_menu_empty
+    | expectedMenu actualMenu |
+
+    expectedMenu := {'Label_01'. 'Label_02'. 'Label_03'}.
+
+    builder
+        perspective: CustomPerspective classPerspective;
+        menu: menu;
+        submenuLabel: 'SomeLabel';
+        buildMenu.    
+
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Modified: / 28-12-2014 / 22:41:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_for_context_filter
+    | expectedMenu actualMenu |
+
+    (self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #(Group_02);
+        addGenerator: 'Generator_03' group: #();
+        addGenerator: 'Generator_04' group: #(Group_01);
+        addGenerator: 'Generator_05' group: #(Group_01 Subgroup_01);
+        addGenerator: 'Generator_06' group: #(Group_01);
+        addGenerator: 'Generator_07' group: #(Group_01 Subgroup_01))
+            objectAttributeAt: #availableInContext: put: false. "To have at least one generator not avilable for context"
+
+    "Not present generators"
+    (self addGenerator: 'Generator_08' group: #())
+        objectAttributeAt: #availableForProgrammingLanguagesInContext: put: false.
+    (self addGenerator: 'Generator_09' group: #())
+        objectAttributeAt: #availableInPerspective: put: false.
+    self addGenerator: 'Generator_10' group: #().
+
+    menu := builder buildMenuForContext: CustomSubContext new filter: [ :generator |
+        generator label ~= 'Generator_10'
+    ].
+
+    expectedMenu := {
+        'Generator_01'.
+        'Generator_03'.
+        '-'.
+        'Generator_04'.
+        'Generator_06'.
+        '-'.
+        'Generator_02'.
+        '-'.
+        'Generator_05'.
+        'Generator_07'.
+    }.
+
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Modified (comment): / 28-12-2014 / 22:35:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators
+    | expectedMenu actualMenu navigationState |
+
+    expectedMenu := {
+        'Label_01'.
+        'Label_02'. 
+        'Translated BunchOfGenerators'. 
+        {'Translated Generator_01'. 'Translated Generator_03'}.
+        'Label_03'.
+    }.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #();
+        addGenerator: 'Generator_03' group: #().
+
+    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+    provider last
+        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == CustomMenuBuilderTests name'.
+
+    navigationState := Tools::NavigationState new.
+    navigationState selectedClasses value: {CustomMenuBuilderTests}.
+
+    builder
+        perspective: CustomPerspective classPerspective;
+        menu: menu;
+        submenuLabel: 'BunchOfGenerators';
+        afterMenuItemLabelled: 'Label_02';
+        generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring label ~= 'Generator_02' ];
+        navigationState: navigationState;
+        resources: resources;
+        buildMenu.    
+
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu.
+
+    (menu menuItemAt: 3) submenuChannel value itemsDo: [ :item | 
+        self assert: item enabled value
+    ].
+
+    "Created: / 28-12-2014 / 22:48:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:09:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_empty_builder
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #();
+        addGenerator: 'Generator_03' group: #().
+
+    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+    provider last
+        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.
+
+    self should: [
+        builder buildMenu
+    ] raise: Error suchThat: [ :error |
+        (error description) = 'Attributes named menu and perspective are required.'
+    ].
+
+    "Created: / 04-01-2015 / 15:31:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_empty_label
+    | expectedMenu actualMenu navigationState |
+
+    expectedMenu := {
+        'Label_01'.
+        'Label_02'. 
+        'Label_03'.
+        'Unknown menu label'.
+        {'Generator_01'. 'Generator_02'. 'Generator_03'}
+    }.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #();
+        addGenerator: 'Generator_03' group: #().
+
+    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+    provider last
+        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == #CustomMenuBuilderTests'.
+
+    navigationState := Tools::NavigationState new.
+    navigationState selectedClasses value: {CustomMenuBuilderTests}.
+
+    builder
+        perspective: CustomPerspective classPerspective;
+        menu: menu;
+        buildMenu.    
+
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Created: / 04-01-2015 / 15:44:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_nil_label
+    | expectedMenu actualMenu printer expectedError actualError |
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #().
+
+    provider last objectAttributeAt: #label put: nil.  
+
+    printer := mock mockOf: Object.
+    printer compileMockMethod: 'showCR: message 
+        (self objectAttributeAt: #showCR:) add: message';
+        objectAttributeAt: #showCR: put: OrderedCollection new.
+
+    builder
+        perspective: CustomPerspective classPerspective;
+        menu: menu;
+        submenuLabel: 'BunchOfGenerators';
+        errorPrinter: printer;
+        buildMenu.
+
+    expectedError := OrderedCollection new.
+
+    actualError := printer objectAttributeAt: #showCR:.
+    self assert: expectedError = actualError.
+
+    expectedMenu := {
+        'Label_01'.
+        'Label_02'.
+        'Label_03'.
+        'BunchOfGenerators'. 
+        {'Generator_01'}.
+    }.
+
+    actualMenu := self menuItemLabels.
+    self assert: expectedMenu = actualMenu.
+
+    "Created: / 01-02-2015 / 20:25:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_should_implement_error
+    | expectedMenu actualMenu printer expectedError actualError |
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #().
+
+    provider last compileMockMethod: 'availableInPerspective: perspective 
+        self label = ''Generator_02'' ifTrue: [
+            self shouldImplement
+        ].
+        ^ true'.  
+
+    printer := mock mockOf: Object.
+    printer compileMockMethod: 'showCR: message 
+        (self objectAttributeAt: #showCR:) add: message';
+        objectAttributeAt: #showCR: put: OrderedCollection new.
+
+    builder
+        perspective: CustomPerspective classPerspective;
+        menu: menu;
+        submenuLabel: 'BunchOfGenerators';
+        errorPrinter: printer;
+        buildMenu.
+
+    expectedError := OrderedCollection 
+        with: 'An error occured when selecting code generators/refactorings.'
+        with: 'Class: Unknown class name Error: functionality has to be implemented: a ', provider last className, '>>availableInPerspective:'.
+
+    actualError := printer objectAttributeAt: #showCR:.
+    self assert: expectedError = actualError.
+
+    expectedMenu := {
+        'Label_01'.
+        'Label_02'.
+        'Label_03'.
+        'BunchOfGenerators'. 
+        {'Generator_01'}.
+    }.
+
+    actualMenu := self menuItemLabels.
+    self assert: expectedMenu = actualMenu.
+
+    "Created: / 01-02-2015 / 20:19:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_with_subclass_responsibility_error
+    | expectedMenu actualMenu printer expectedError actualError |
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #().
+
+    provider last compileMockMethod: 'availableInPerspective: perspective 
+        self label = ''Generator_02'' ifTrue: [
+            self subclassResponsibility
+        ].
+        ^ true'.  
+
+    printer := mock mockOf: Object.
+    printer compileMockMethod: 'showCR: message 
+        (self objectAttributeAt: #showCR:) add: message';
+        objectAttributeAt: #showCR: put: OrderedCollection new.
+
+    builder
+        perspective: CustomPerspective classPerspective;
+        menu: menu;
+        submenuLabel: 'BunchOfGenerators';
+        errorPrinter: printer;
+        buildMenu.
+
+    expectedError := OrderedCollection 
+        with: 'An error occured when selecting code generators/refactorings.'
+        with: 'Class: Unknown class name Error: "availableInPerspective:" method must be reimplemented in subclass'.
+
+    actualError := printer objectAttributeAt: #showCR:.
+    self assert: expectedError = actualError.
+
+    expectedMenu := {
+        'Label_01'.
+        'Label_02'.
+        'Label_03'.
+        'BunchOfGenerators'. 
+        {'Generator_01'}.
+    }.
+
+    actualMenu := self menuItemLabels.
+    self assert: expectedMenu = actualMenu.
+
+    "Created: / 01-02-2015 / 19:17:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 01-02-2015 / 20:17:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_build_menu_two_generators_without_filter
+    | expectedMenu actualMenu navigationState |
+
+    expectedMenu := {
+        'Label_01'.
+        'Label_02'. 
+        'Translated BunchOfGenerators'. 
+        {'Translated Generator_01'. 'Translated Generator_02'. 'Translated Generator_03'}.
+        'Label_03'.
+    }.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #();
+        addGenerator: 'Generator_03' group: #().
+
+    "Create some methods which actually uses context and perspective to be sure that they are correctly created"
+    provider last
+        compileMockMethod: 'availableInPerspective: perspective ^ perspective isClassPerspective';
+        compileMockMethod: 'availableInContext: context ^ context selectedClasses first name == CustomMenuBuilderTests name'.
+
+    navigationState := Tools::NavigationState new.
+    navigationState selectedClasses value: {CustomMenuBuilderTests}.
+
+    builder
+        perspective: CustomPerspective classPerspective;
+        menu: menu;
+        submenuLabel: 'BunchOfGenerators';
+        afterMenuItemLabelled: 'Label_02';
+        navigationState: navigationState;
+        resources: resources;
+        buildMenu.    
+
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu.
+
+    (menu menuItemAt: 3) submenuChannel value itemsDo: [ :item | 
+        self assert: item enabled value
+    ].
+
+    "Created: / 29-12-2014 / 09:33:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:09:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_groups_sort_block
+    | expectedGroups actualGroups |
+
+    actualGroups := {
+        #(Group_09 Subgroup_02 Subsubgroup_02).
+        #(Group_09 Subgroup_01 Subsubgroup_02).
+        #(Group_09 Subgroup_01 Subsubgroup_01).
+        #(Group_01).
+        #(Group_09 Subgroup_01).
+        #(Group_01 Subgroup_01).
+        #(Group_03).
+        #(Group_02 Subgroup_02).
+        #(Group_02 Subgroup_01).
+        #(Group_10).
+        #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
+        #().
+    }.
+
+    "Maybe better order?"
+    "
+    expectedGroups := {
+        #().
+        #(Group_01).
+        #(Group_01 Subgroup_01).
+        #(Group_02 Subgroup_01).
+        #(Group_02 Subgroup_02).
+        #(Group_03).
+        #(Group_09 Subgroup_01).
+        #(Group_09 Subgroup_01 Subsubgroup_01).
+        #(Group_09 Subgroup_01 Subsubgroup_02).
+        #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
+        #(Group_09 Subgroup_02 Subsubgroup_02).
+        #(Group_10)
+    }. "
+
+    expectedGroups := {
+        #().
+        #(Group_01).
+        #(Group_03).
+        #(Group_10).
+        #(Group_01 Subgroup_01).
+        #(Group_02 Subgroup_01).
+        #(Group_02 Subgroup_02).
+        #(Group_09 Subgroup_01).
+        #(Group_09 Subgroup_01 Subsubgroup_01).
+        #(Group_09 Subgroup_01 Subsubgroup_02).
+        #(Group_09 Subgroup_02 Subsubgroup_02).
+        #(Group_09 Subgroup_01 Subsubgroup_02 Subsubsubgroup_01).
+    }.
+
+    actualGroups sort: builder groupsSortBlock.    
+    
+    self assert: expectedGroups = actualGroups
+
+    "Modified (format): / 28-12-2014 / 21:54:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_place_menu_item_after_menu_item_labeled_for_menu_item_empty
+    | menuItem expectedMenuItemLabels actualMenuItemLabels |
+
+    menuItem := MenuItem label: 'SomeLabel'.
+
+    expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'Label_03'. 'SomeLabel'}.
+
+    builder placeMenuItem: menuItem afterMenuItemLabeled: nil forMenu: menu.
+
+    actualMenuItemLabels := self menuItemLabels.
+
+    self assert: expectedMenuItemLabels = actualMenuItemLabels
+
+    "Created: / 04-01-2015 / 15:41:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_place_menu_item_after_menu_item_labeled_for_menu_item_found
+    | menuItem expectedMenuItemLabels actualMenuItemLabels |
+
+    menuItem := MenuItem label: 'SomeLabel'.
+
+    expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'SomeLabel'. 'Label_03'}.
+
+    builder placeMenuItem: menuItem afterMenuItemLabeled: 'Label_02' forMenu: menu.
+
+    actualMenuItemLabels := self menuItemLabels.
+
+    self assert: expectedMenuItemLabels = actualMenuItemLabels
+
+    "Modified: / 28-12-2014 / 10:41:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_place_menu_item_after_menu_item_labeled_for_menu_item_not_found
+    | menuItem expectedMenuItemLabels actualMenuItemLabels |
+
+    menuItem := MenuItem label: 'SomeLabel'.
+
+    expectedMenuItemLabels := {'Label_01'. 'Label_02'. 'Label_03'. 'SomeLabel'}.
+
+    builder placeMenuItem: menuItem afterMenuItemLabeled: 'NotExistingLabel' forMenu: menu.
+
+    actualMenuItemLabels := self menuItemLabels.
+
+    self assert: expectedMenuItemLabels = actualMenuItemLabels
+
+    "Created: / 28-12-2014 / 10:45:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMenuBuilderTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMock.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,316 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomMock
+	instanceVariableNames:'mockedClasses'
+	classVariableNames:'MockCount'
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomMock class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Helper for creating mocked classes.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomMock class methodsFor:'initialization'!
+
+initialize
+    "Invoked at system start or when the class is dynamically loaded."
+
+    "/ please change as required (and remove this comment)
+
+    MockCount := 0.
+
+    "Modified: / 11-05-2015 / 09:25:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomMock class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    MockCount isNil ifTrue: [ 
+        MockCount := 0
+    ].
+
+    ^ self basicNew initialize.
+
+    "Created: / 15-06-2014 / 19:20:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'accessing'!
+
+mockCount
+    "Returns how many mock has been created ever since"
+
+    ^ MockCount
+
+    "Created: / 22-09-2014 / 23:05:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+variableNameForClassMockedSelectors
+
+    ^ 'MockedClassSelectors'
+
+    "Created: / 11-07-2014 / 10:16:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+variableNameForInstanceMockedSelectors
+
+    ^ 'MockedSelectors'
+
+    "Created: / 11-07-2014 / 10:15:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'code generation'!
+
+createMockClassOf: aClass mockNumber: aNumber
+    "Returns generated mock subclass of given class 
+    to support custom return values of overriden methods"
+
+    | mockClass className mockClassName |
+
+    className := aClass theNonMetaclass name.
+    mockClassName := ('CustomMock', aNumber asString, 'Of', className copyReplaceAll: $: with: $_).
+
+    Class withoutUpdatingChangesDo:[
+        | definition |
+
+        definition := className, ' subclass:#''SmallSense::', mockClassName, '''
+            instanceVariableNames:''''
+            classVariableNames:''MockedSelectors MockedClassSelectors''
+            poolDictionaries:''''
+            category:''Interface-Refactoring-Custom-Mocks'''.
+
+        (InteractiveAddClassChange definition: definition) execute.
+
+        mockClass := Smalltalk classNamed: ('SmallSense::', mockClassName) asSymbol.
+
+        self createMockMethodWithSingleValue: mockClass.
+        self createMockMethodWithCompileMethod: mockClass.
+    ].
+
+    ^ mockClass
+
+    "Created: / 15-06-2014 / 19:15:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 22:46:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-05-2015 / 19:39:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+createMockGetters: aMockClass forSelectors: aSelectors
+    "Generates mock getter method for each name"
+
+    aSelectors do: [ :selector | 
+        | getterSource template |
+
+        template := Method methodDefinitionTemplateForSelector: selector asSymbol.
+
+        getterSource := template, ' ^ self objectAttributeAt: #', selector.
+
+        aMockClass compile: getterSource classified: 'mocking' logged: false.
+    ]
+
+    "Created: / 28-12-2014 / 14:58:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMockMethod: aMockClass methodSource: aSource mockedSelectorsVariableName: aMockedSelectorsVariableName
+    "Generates mock method for given mock class 
+    to support custom method value/implementation by some value/block
+    (depends on given source)"
+
+    | newSource |
+
+    newSource := aSource copyReplaceAll: '`mockedSelectorsVariableName' with: aMockedSelectorsVariableName.
+    aMockClass compile: newSource classified: 'mocking' logged:false.
+
+    "Created: / 21-09-2014 / 21:51:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-09-2014 / 21:26:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMockMethodWithCompileMethod: aMockClass
+    "Generates mock method for given mock class 
+    to support custom method implementation by given method source"
+
+    self
+        createMockMethod: aMockClass theMetaclass
+        methodSource: self compileMockMethodSource
+        mockedSelectorsVariableName: ''.
+
+    self
+        createMockMethod: aMockClass theNonMetaclass
+        methodSource: self compileMockMethodSource
+        mockedSelectorsVariableName: ''.
+
+    "Created: / 23-09-2014 / 22:44:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMockMethodWithSingleValue: aMockClass
+    "Generates mock method for given mock class 
+    to support custom return values of overriden methods"
+
+    | instVarName classVarName |
+
+    classVarName := self variableNameForClassMockedSelectors.
+
+    self
+        createMockMethod: aMockClass theMetaclass
+        methodSource: (self singleValueMethodSource: classVarName)
+        mockedSelectorsVariableName: classVarName.
+
+    instVarName := self variableNameForInstanceMockedSelectors.
+
+    self
+        createMockMethod: aMockClass theNonMetaclass
+        methodSource: (self singleValueMethodSource: instVarName)
+        mockedSelectorsVariableName: instVarName.
+
+    "Created: / 21-09-2014 / 21:45:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'code generation - sources'!
+
+compileMockMethodSource
+    "Returns mock method source code which will compile method source."
+
+    ^ 'compileMockMethod: aSourceCode
+
+    self class compile:aSourceCode classified:''mocks'' logged:false'.
+
+    "Created: / 23-09-2014 / 22:31:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+singleValueMethodSource: aMockedSelectorsVariableName
+    "Returns mock method source code for given variable name
+    which holds mocked selectors and its values. 
+    These values are constants (within method) like numbers, classes, objects..."
+
+    ^ 'mockSelector: aSelector withReturnValue: aValue
+
+    | classQuery superclassMethod methodDefinitionTemplate |
+
+    `mockedSelectorsVariableName isNil ifTrue: [ 
+        `mockedSelectorsVariableName := Dictionary new
+    ].
+
+    `mockedSelectorsVariableName at: aSelector asSymbol put: aValue.
+
+    classQuery := CustomClassQuery new.
+    superclassMethod := classQuery methodForSuperclassSelector: aSelector class: self class.
+    methodDefinitionTemplate := superclassMethod methodDefinitionTemplate asString.
+
+    self compileMockMethod: (methodDefinitionTemplate, ''
+        ^ `mockedSelectorsVariableName at: #'', aSelector)'.
+
+    "Created: / 10-07-2014 / 22:23:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-09-2014 / 21:00:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'initialization'!
+
+initialize
+
+    mockedClasses := OrderedCollection new
+
+    "Created: / 15-06-2014 / 19:19:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'mock creation'!
+
+mockClassOf: aClass
+    "Creates a mock class of given class"
+    | mockClass |
+
+    mockClass := self createMockClassOf: aClass mockNumber: MockCount.
+
+    MockCount := MockCount + 1.
+    mockedClasses add: mockClass.
+
+    ^ mockClass
+
+    "Created: / 15-06-2014 / 23:41:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 22-09-2014 / 23:11:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+mockOf: aClass
+    "Creates a mock class instance of given class"
+
+    ^ (self mockClassOf: aClass) new
+
+    "Created: / 15-06-2014 / 23:44:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock methodsFor:'mock release'!
+
+unmockAll
+
+    Class withoutUpdatingChangesDo:[
+        mockedClasses do: [ :class |
+            class removeFromSystem
+        ].
+
+        mockedClasses removeAll
+    ]
+
+    "Created: / 15-06-2014 / 19:30:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-09-2014 / 21:47:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMock class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
+
+CustomMock initialize!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMockTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,473 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomMockTests
+	instanceVariableNames:'model mock testCompleted'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomMockTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomMockTests methodsFor:'initialization & release'!
+
+setUp
+
+    model := CustomNamespace new.
+    mock := CustomMock new.
+    testCompleted := false.
+
+    "Modified: / 09-10-2014 / 09:34:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    model undoChanges.
+    mock unmockAll
+
+    "Modified: / 19-10-2014 / 14:56:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMockTests methodsFor:'private'!
+
+performTest
+    Class withoutUpdatingChangesDo:[
+        self perform: testSelector sunitAsSymbol
+    ]
+
+    "Created: / 24-09-2014 / 21:30:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMockTests methodsFor:'tests'!
+
+test_class_and_instance_methods_overriden_by_compiled_mock_method
+    | class mockClass |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: (class theMetaclass) protocol: 'p' source: 'aSelector_01: aParam
+        ^ 10'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+        ^ 15'.
+
+        self assert: (class aSelector_01: nil) = 10.
+        self assert: (class new aSelector_01: nil) = 15.
+
+        mockClass := mock mockClassOf: class.
+        mockClass compileMockMethod: 'aSelector_01: aParam ^ 20'.
+        mockClass new compileMockMethod: 'aSelector_01: aParam ^ 25'.
+
+        self assert: (mockClass aSelector_01: nil) = 20.
+        self assert: (mockClass new aSelector_01: nil) = 25.
+
+        testCompleted := true.
+
+    ] ensure: [
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:53:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_methods_overriden_by_compiled_mock_method
+    | class mockClass |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: (class theMetaclass) protocol: 'p' source: 'aSelector_01: aParam
+        ^ 10'.
+        model createMethodImmediate: (class theMetaclass) protocol: 'p' source: 'aSelector_02: aParam
+
+        (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+        ^ false'.
+
+        self assert: (class aSelector_02: nil).
+
+        mockClass := mock mockClassOf: class.
+        mockClass compileMockMethod: 'aSelector_01: aParam ^ 20'.
+
+        self assert: (mockClass aSelector_01: nil) = 20.
+        self assert: (mockClass aSelector_02: nil) not.
+
+        testCompleted := true.
+
+    ] ensure: [
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:54:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_methods_overriden_by_mock
+    | class mockClass |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: class theMetaclass protocol: 'p' source: 'aSelector_01: aParam
+        ^ 10'.
+        model createMethodImmediate: class theMetaclass protocol: 'p' source: 'aSelector_02: aParam
+
+        (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+        ^ false'.
+
+        self assert: (class aSelector_02: nil).
+
+        mockClass := mock mockClassOf: class.
+        mockClass mockSelector: #aSelector_01: withReturnValue: 20.
+
+        self assert: (mockClass aSelector_01: nil) = 20.
+        self assert: (mockClass aSelector_02: nil) not. 
+
+        testCompleted := true.
+
+    ] ensure: [
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 10-07-2014 / 19:35:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 22-09-2014 / 23:14:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_mock_getters_for_selectors    
+    | expectedSource01 actualSource01 expectedSource02 actualSource02 mockClass |
+
+    mockClass := mock mockClassOf: Object.
+    mock createMockGetters: mockClass forSelectors: {'selector'. 'selector:'}.
+
+    expectedSource01 := 'selector ^ self objectAttributeAt: #selector'.
+    expectedSource02 := 'selector:arg ^ self objectAttributeAt: #selector:'.
+
+    actualSource01 := mockClass sourceCodeAt:#selector.
+    actualSource02 := mockClass sourceCodeAt:#selector:.
+
+    self assert: expectedSource01 = actualSource01.           
+    self assert: expectedSource02 = actualSource02.
+
+    "Modified: / 28-12-2014 / 15:29:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method
+    | class mockClassInstance |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+        ^ 10'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_02: aParam
+
+        (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+        ^ false'.
+
+        self assert: (class new aSelector_02: nil).
+
+        mockClassInstance := mock mockOf: class.
+        mockClassInstance compileMockMethod: 'aSelector_01: aParam ^ 20'.
+
+        self assert: (mockClassInstance aSelector_01: nil) = 20.
+        self assert: (mockClassInstance aSelector_02: nil) not.
+
+
+        testCompleted := true.
+
+    ] ensure: [ 
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:54:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_value_with_params
+    | class mockClassInstance |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+        ^ 10'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_02: aParam
+
+        (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+        ^ false'.
+
+        self assert: (class new aSelector_02: nil).
+
+        mockClassInstance := mock mockOf: class.
+        mockClassInstance compileMockMethod: 'aSelector_01: aParam
+            aParam = 5 ifTrue: [
+                ^ 10
+            ].
+
+            ^ 30'.
+
+        self assert: (mockClassInstance aSelector_01: 5) = 10.
+        self assert: (mockClassInstance aSelector_02: 3) not.
+
+        testCompleted := true.
+
+    ] ensure: [ 
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:54:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_value_with_two_params
+    | class mockClassInstance |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: arg_01 param_02: arg_02
+        ^ 10'.
+
+        self assert: ((class new aSelector_01: 1 param_02: 2) = 10).
+
+        mockClassInstance := mock mockOf: class.
+        mockClassInstance compileMockMethod: 'aSelector_01:arg_01 param_02:arg_02 ^ arg_01 + arg_02'.
+
+        self assert: (mockClassInstance aSelector_01: 3 param_02: 3) = 6.
+
+        testCompleted := true.
+
+    ] ensure: [ 
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:54:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_with_none_params
+    | class mockClassInstance |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_01
+        ^ 10'.
+
+        self assert: (class new aSelector_01 = 10).
+
+        mockClassInstance := mock mockOf: class.
+        mockClassInstance compileMockMethod: 'aSelector_01 ^ 30'.
+
+        self assert: (mockClassInstance aSelector_01) = 30.
+
+        testCompleted := true.
+
+    ] ensure: [
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:54:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_compiled_mock_method_with_three_params
+    | class mockClassInstance |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: arg_01 param_02: arg_02 param_03: arg_03
+        ^ 10'.
+
+        self assert: ((class new aSelector_01: 1 param_02: 2 param_03: 3) = 10).
+
+        mockClassInstance := mock mockOf: class.
+        mockClassInstance compileMockMethod: 'aSelector_01:arg_01 param_02:arg_02 param_03:arg_03  
+            ^ arg_01 + arg_02 + arg_03'.
+
+        self assert: (mockClassInstance aSelector_01: 3 param_02: 3 param_03: 3) = 9.
+
+        testCompleted := true.
+
+    ] ensure: [ 
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:55:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_overriden_by_mock
+    | class mockClassInstance |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_01: aParam
+        ^ 10'.
+        model createMethodImmediate: class protocol: 'p' source: 'aSelector_02: aParam
+
+        (self aSelector_01: aParam) = 10 ifTrue: [ ^ true ].
+
+        ^ false'.
+
+        self assert: (class new aSelector_02: nil).
+
+        mockClassInstance := mock mockOf: class.
+        mockClassInstance mockSelector: #aSelector_01: withReturnValue: 20.
+
+        self assert: (mockClassInstance aSelector_01: nil) = 20.
+        self assert: (mockClassInstance aSelector_02: nil) not.
+
+
+        testCompleted := true.
+
+    ] ensure: [ 
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 15-06-2014 / 20:19:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 22-09-2014 / 23:14:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_mock_count_incremented_when_new_class_created
+    | class mockCount |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+
+        mockCount := mock mockCount.  
+
+        mock mockOf: class.
+
+        self assert: (mockCount + 1) = (mock mockCount).
+
+        testCompleted := true.
+
+    ] ensure: [ 
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 22-09-2014 / 23:05:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:19:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_namespace_not_created_for_class_with_namespace
+    "If class name contains also namespace name then it is created along with the class.
+    Assert that namespace is not created, because there is no use for it in temporary class
+    - only leaves mess in the browser."
+    | class expectedNameSpaceCount actualNameSpaceCount |
+
+    [
+        class := model createClassImmediate: 'DummyNameSpace01::DummyClass01'.
+
+        expectedNameSpaceCount := NameSpace allNameSpaces size.
+        self assert: expectedNameSpaceCount > 1.
+
+        mock mockClassOf: class.
+
+        actualNameSpaceCount := NameSpace allNameSpaces size.
+
+        self assert: expectedNameSpaceCount = actualNameSpaceCount.
+
+        testCompleted := true.
+
+    ] ensure: [
+        (Smalltalk at: #DummyNameSpace01) notNil ifTrue: [ 
+            Class withoutUpdatingChangesDo: [  
+                (Smalltalk at: #DummyNameSpace01) removeFromSystem
+            ]
+        ].
+
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 24-01-2015 / 19:22:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:19:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_unmock_all
+    | class mockClass mockClassName |
+
+    [
+        class := model createClassImmediate: 'TestClassForMockTestCase' superClassName: 'Object'.
+
+        mockClass := mock mockClassOf: class.
+        mockClassName := mockClass name.
+
+        self assert: (Smalltalk at: mockClassName) isNil not.
+        mock unmockAll.
+        self assert: (Smalltalk at: mockClassName) isNil.
+
+        testCompleted := true.
+
+    ] ensure: [
+        "Need to test if test is complete, because in this case
+        sometimes happens that the test terminates and is marked as success."
+        self assert: testCompleted
+    ].
+
+    "Created: / 23-09-2014 / 22:58:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMockTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMultiSetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,161 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomMultiSetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Multi-Setter Method(s) for selected instance variables'
+
+    "Modified: / 13-07-2014 / 19:06:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Getters')
+
+    "Created: / 22-08-2014 / 18:54:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Multi-Setter Method(s)'
+
+    "Modified: / 13-07-2014 / 19:06:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+
+    ^ aCustomContext selectedClasses notEmptyOrNil and: [ 
+        aCustomContext selectedVariables notEmptyOrNil and: [ 
+            aCustomContext selectedVariables size >= 2
+        ]
+    ]
+
+    "Created: / 13-07-2014 / 19:14:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+createMultiSetterMethodForVariables: aVariableNames inClass: aClass
+    "Creates multi-setter access method for given variable names and class"
+
+    | setterSelector comment assignVariablesCode |
+
+    setterSelector := ''.
+    comment := ''.
+    assignVariablesCode := ''.
+
+    userPreferences generateCommentsForSetters ifTrue: [ 
+        comment := '"set instance variables"'.
+    ].
+
+    aVariableNames do: [ :variableName |
+        | argumentName |
+
+        argumentName := variableName asString, 'Arg'.
+
+        setterSelector := setterSelector, variableName asString, ': ', argumentName, ' '.
+        assignVariablesCode := assignVariablesCode, variableName asString, ' := ', argumentName, '. '.
+    ].
+
+    model createMethod
+        class: aClass;
+        protocol: 'accessing';
+        source: '`@setterSelector
+            `"comment
+
+            `@assignVariablesCode
+        ';
+        replace: '`@setterSelector' with: setterSelector asSymbol;
+        replace: '`"comment' with: comment;
+        replace: '`@assignVariablesCode' with: assignVariablesCode;
+        compile.
+
+    "Created: / 13-07-2014 / 20:45:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-10-2014 / 19:00:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Creates multi-setter access methods for given context"
+
+    aCustomContext selectedClasses do:[ :class | 
+        self
+            createMultiSetterMethodForVariables: aCustomContext selectedVariables
+            inClass: class 
+    ].
+
+    "Modified: / 13-07-2014 / 20:45:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomMultiSetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,165 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomMultiSetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomMultiSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomMultiSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomMultiSetterMethodsCodeGenerator new
+! !
+
+!CustomMultiSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_available_in_context_for_none_variable_names
+
+    context
+        selectedClasses: (Array with: self class).
+
+    self assert: (generatorOrRefactoring class availableInContext: context) not.
+
+    "Created: / 13-07-2014 / 20:11:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_for_one_variable_name
+
+    context
+        selectedClasses: (Array with: self class);
+        selectedVariables: (Array with: 'var_01').
+
+    self assert: (generatorOrRefactoring class availableInContext: context) not.
+
+    "Created: / 13-07-2014 / 20:08:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_for_three_variable_names
+
+    context
+        selectedClasses: (Array with: self class);
+        selectedVariables: (Array with: 'var_01' with: 'var_02' with: 'var_03').
+
+    self assert: (generatorOrRefactoring class availableInContext: context).
+
+    "Created: / 13-07-2014 / 20:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_for_two_variable_names
+
+    context
+        selectedClasses: (Array with: self class);
+        selectedVariables: (Array with: 'var_01' with: 'var_02').
+
+    self assert: (generatorOrRefactoring class availableInContext: context).
+
+    "Created: / 13-07-2014 / 20:09:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_multi_setter_method_generated_with_comments_for_three_variables
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: true.
+
+    expectedSource := 'instanceVariable_01:instanceVariable_01Arg instanceVariable_02:instanceVariable_02Arg instanceVariable_03:instanceVariable_03Arg
+    "set instance variables"
+
+    instanceVariable_01 := instanceVariable_01Arg.
+    instanceVariable_02 := instanceVariable_02Arg.
+    instanceVariable_03 := instanceVariable_03Arg.'.
+
+    self executeGeneratorInContext: #classWithThreeInstanceVariables.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable_01:instanceVariable_02:instanceVariable_03:
+
+    "Created: / 13-07-2014 / 21:55:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 22:37:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_multi_setter_method_generated_with_comments_for_two_variables
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: true.
+
+    expectedSource := 'instanceVariable_01:instanceVariable_01Arg instanceVariable_02:instanceVariable_02Arg 
+    "set instance variables"
+
+    instanceVariable_01 := instanceVariable_01Arg.
+    instanceVariable_02 := instanceVariable_02Arg.'.
+
+    self executeGeneratorInContext: #classWithTwoInstanceVariables.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable_01:instanceVariable_02:
+
+    "Created: / 13-07-2014 / 21:53:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 22:37:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_multi_setter_method_generated_without_comments_for_two_variables
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: false.
+
+    expectedSource := 'instanceVariable_01:instanceVariable_01Arg instanceVariable_02:instanceVariable_02Arg 
+    instanceVariable_01 := instanceVariable_01Arg.
+    instanceVariable_02 := instanceVariable_02Arg.'.
+
+    self executeGeneratorInContext: #classWithTwoInstanceVariables.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable_01:instanceVariable_02:
+
+    "Created: / 13-07-2014 / 21:57:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 22:37:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomMultiSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNamespace.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,455 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+RBNamespace subclass:#CustomNamespace
+	instanceVariableNames:'changeManager formatter classModelClass methodModelClass
+		sourceCodeGeneratorClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomNamespace class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomNamespace methodsFor:'accessing'!
+
+at: aClassName
+
+    ^ self classNamed: aClassName asSymbol
+
+    "Created: / 15-11-2014 / 17:30:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+changeManager
+    ^ changeManager
+!
+
+changeManager:something
+    changeManager := something.
+!
+
+classModelClass
+    "Returns class which represents Class in model in which we make changes (add class, rename class ...)."
+
+    ^ classModelClass
+
+    "Modified (comment): / 09-10-2014 / 11:14:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classModelClass: aClass
+    "see classModelClass"
+
+    classModelClass := aClass.
+
+    "Modified (comment): / 09-10-2014 / 11:15:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter
+    ^ formatter
+
+    "Created: / 28-08-2014 / 23:19:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter: aFormatter
+    formatter := aFormatter
+
+    "Created: / 28-08-2014 / 23:19:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodModelClass
+    "Returns class which represents Method in model in which we make changes (add method, change method source ...)."
+
+    ^ methodModelClass
+
+    "Modified (comment): / 09-10-2014 / 11:17:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodModelClass: aClass
+    "see methodModelClass"
+
+    methodModelClass := aClass.
+
+    "Modified (comment): / 09-10-2014 / 11:16:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+putModelClass: aModelClass 
+    "Stores model class (e.g. RBClass) in this model so we can work further with 
+    the given class and the modifications done to the given class 
+    are reflected in this model (represented by CustomNamespace/RBNamespace)."
+    | classIndex name isClassUndefined |
+
+    classIndex := 1.
+    name := aModelClass name.
+    aModelClass isMeta ifTrue: [ 
+        classIndex := 2.
+        name := aModelClass theNonMetaclass name.
+    ].
+
+    isClassUndefined := true.
+    newClasses at: name ifPresent: [ :classes |
+        isClassUndefined := false.
+        classes at: classIndex put: aModelClass  
+    ].
+
+    changedClasses at: name ifPresent: [ :classes |
+        isClassUndefined := false.
+        classes at: classIndex put: aModelClass  
+    ].
+
+    isClassUndefined ifTrue: [
+        self error: 'Class has to be defined in the model - see defineClass: .'.
+    ]
+
+    "Created: / 04-11-2014 / 00:03:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-11-2014 / 01:07:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGenerator
+    "Returns initialized source code generator (CodeGenerator, CustomSourceCodeGenerator)"
+    | sourceCodeGenerator |
+
+    sourceCodeGenerator := self sourceCodeGeneratorClass new.
+    sourceCodeGenerator formatter: formatter.
+    ^ sourceCodeGenerator.
+
+    "Created: / 19-09-2014 / 20:56:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 09-10-2014 / 11:35:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 27-11-2014 / 19:32:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGeneratorClass
+    "Returns code generator class which supports search & replace in method source code and formatting"
+
+    ^ sourceCodeGeneratorClass
+
+    "Modified (comment): / 09-10-2014 / 11:34:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+sourceCodeGeneratorClass: aClass
+    "see sourceCodeGeneratorClass"
+
+    sourceCodeGeneratorClass := aClass.
+
+    "Modified (comment): / 09-10-2014 / 11:34:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'accessing-classes'!
+
+classNamed: aName 
+    "Returns an RBClass instance stored under given class name
+    or nil if nothing found"
+
+    ^ super classNamed: aName asSymbol
+
+    "Created: / 19-11-2014 / 21:19:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+metaclassNamed: aName 
+    "Returns an RBMetaclass instance stored under given class name
+    or nil if nothing found"
+
+    ^ super metaclassNamed: aName asSymbol
+
+    "Created: / 19-11-2014 / 21:20:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'changes'!
+
+defineClass: aString
+    "Defines a class withing this model by its definition string.
+    Here is same behaviour as in RBNamespace, but we added private
+    class support."
+    | change |
+
+    change := super defineClass: aString.
+    change privateInClassName notNil ifTrue: [ 
+        | class |
+
+        class := self classNamed: change changeClassName.
+        class owningClass: (self classNamed: change privateInClassName)
+    ].
+
+    ^ change
+
+    "Created: / 29-11-2014 / 14:39:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'code creation'!
+
+createClass
+    "Much like createMethod, but for class"
+
+    ^ self classModelClass new
+        model: self;
+        superclass: (self classNamed: #Object);
+        instanceVariableNames: #();
+        classVariableNames: #();
+        poolDictionaryNames: #();
+        yourself.
+
+    "Created: / 09-04-2014 / 21:38:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 22:31:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethod
+    "
+    Creates, returns method representation
+    so code changes can be created withing this class as one undo change
+    "
+
+    ^ self methodModelClass new
+        model: self;
+        sourceCodeGenerator: self sourceCodeGenerator;
+        yourself.
+
+    "Created: / 09-04-2014 / 23:54:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 22:32:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'code creation - immediate'!
+
+createClassImmediate: aClassName
+    "Creates class immediately and returns the real class"
+
+    ^ self createClassImmediate: aClassName superClassName: 'Object'
+
+    "Created: / 27-07-2014 / 12:40:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName category: aCategoryName
+    "Creates class immediately and returns the real class"
+
+    ^ self 
+        createClassImmediate: aClassName 
+        superClassName: 'Object' 
+        instanceVariableNames: '' 
+        classVariableNames: ''
+        poolDictionaries: ''
+        category: aCategoryName
+
+    "Created: / 19-10-2014 / 20:55:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName instanceVariableNames: instVarNames
+    "Creates class immediately and returns the real class"
+
+    ^ self 
+        createClassImmediate: aClassName 
+        superClassName: 'Object' 
+        instanceVariableNames: instVarNames 
+        classVariableNames: ''
+
+    "Created: / 23-08-2014 / 22:25:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName
+    "Creates class immediately and returns the real class"
+
+    ^ self 
+        createClassImmediate: aClassName 
+        superClassName: aSuperClassName 
+        instanceVariableNames: '' 
+        classVariableNames: ''
+
+    "Created: / 15-06-2014 / 15:59:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 23-08-2014 / 22:18:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames
+    "Creates class immediately and returns the real class"
+
+    ^ self createClassImmediate: aClassName 
+        superClassName: aSuperClassName 
+        instanceVariableNames: instVarNames 
+        classVariableNames: classVarNames 
+        poolDictionaries: '' 
+        category: ''
+
+    "Created: / 23-08-2014 / 22:18:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-10-2014 / 20:49:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDict category: category
+    "Creates class immediately and returns the real class"
+
+    ^ self createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDict category: category privateIn: nil
+
+    "Created: / 19-10-2014 / 20:47:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-10-2014 / 21:46:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: instVarNames classVariableNames: classVarNames poolDictionaries: poolDict category: category privateIn: privateInClassName
+    "Creates class immediately and returns the real class"
+    | newClassName change |
+
+    newClassName := aClassName.
+
+    privateInClassName isNil ifTrue: [ 
+        change := (InteractiveAddClassChange definition:
+            aSuperClassName asString, ' subclass:#', aClassName asString, '
+                instanceVariableNames:''', instVarNames asString, '''
+                classVariableNames:''', classVarNames asString, '''
+                poolDictionaries:''', poolDict asString, '''
+                category:''', category asString, '''
+        ')
+    ] ifFalse: [ 
+        change := (InteractiveAddClassChange definition:
+            aSuperClassName asString, ' subclass:#', aClassName asString, '
+                instanceVariableNames:''', instVarNames asString, '''
+                classVariableNames:''', classVarNames asString, '''
+                poolDictionaries:''', poolDict asString, '''
+                privateIn:', privateInClassName asString, '
+        ').
+
+        newClassName := privateInClassName asString, '::', aClassName asString.
+    ].
+
+    changeManager performChange: change.  
+
+    ^ Smalltalk classNamed: newClassName
+
+    "Created: / 30-10-2014 / 21:28:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 02-11-2014 / 16:30:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createClassImmediate: aClassName superClassName: aSuperClassName privateIn: privateInClassName
+    "Creates class immediately and returns the real class"
+
+    ^ self createClassImmediate: aClassName superClassName: aSuperClassName instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: '' privateIn: privateInClassName
+
+    "Created: / 30-10-2014 / 21:47:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethodImmediate: aClass protocol: aProtocol source: aSource
+    "Much like createClassImmediate:superClassName:, but for method"
+
+    ^ self createMethodImmediate: aClass protocol: aProtocol source: aSource package: nil
+
+    "Created: / 15-06-2014 / 16:06:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 17-10-2014 / 09:58:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethodImmediate: aClass protocol: aProtocol source: aSource package: aPackageId
+    "Much like createClassImmediate:superClassName:, but for method"
+
+    | selector change |
+
+    change := InteractiveAddMethodChange compile: aSource in: aClass classified: aProtocol.
+
+    (aPackageId notNil and: [ (change class canUnderstand: #package:) ]) ifTrue: [ 
+        change package: aPackageId  
+    ].
+
+    changeManager performChange: change.    
+
+    selector := (Parser parseMethodSpecification: aSource) selector.
+    ^ aClass compiledMethodAt: selector
+
+    "Created: / 17-10-2014 / 09:53:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 02-11-2014 / 16:17:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+createMethodImmediate: aClass source: aSource
+    "Much like createClassImmediate:superClassName:, but for method"
+
+    ^ self createMethodImmediate: aClass protocol: 'protocol' source: aSource
+
+    "Created: / 23-08-2014 / 20:17:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'compiling'!
+
+execute
+    "Performs code changes ( add method, add class, rename class... )
+    so they take in effect ( method is added, class is renamed, ... )
+    with respect to current change manager implementatin - see CustomChangeManager subclasses."
+
+    changeManager performChange: changes
+
+    "Created: / 27-04-2014 / 16:30:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 21-09-2014 / 22:34:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 19-10-2014 / 14:30:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+undoChanges
+    "redo all changes made by execute method"
+
+    changeManager undoChanges
+
+    "Created: / 19-10-2014 / 14:56:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    super initialize.
+    changeManager := SmallSense::CustomLocalChangeManager new.
+    formatter := SmallSense::CustomRBLocalSourceCodeFormatter new.
+    classModelClass := RBClass.
+    methodModelClass := RBMethod.
+    sourceCodeGeneratorClass := CustomSourceCodeGenerator.
+
+    "Created: / 09-04-2014 / 23:44:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 22:33:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:08:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomNamespace methodsFor:'testing'!
+
+isNamespace
+    ^ true
+
+    "Created: / 15-11-2014 / 17:29:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespace class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNamespaceTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,979 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomNamespaceTests
+	instanceVariableNames:'refactoryChangeManager'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomNamespaceTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomNamespaceTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ nil
+
+    "Modified: / 31-05-2014 / 22:48:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests methodsFor:'initialization & release'!
+
+setUp
+
+    super setUp.
+    refactoryChangeManager := RefactoryChangeManager instance.
+
+    "Created: / 16-04-2014 / 21:39:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 31-05-2014 / 22:45:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests methodsFor:'private'!
+
+lastUndoChange
+
+    refactoryChangeManager undoableOperations isEmpty ifTrue: [ 
+        ^ nil 
+    ] ifFalse: [
+        ^ refactoryChangeManager undoChange
+    ].
+
+    "Created: / 16-04-2014 / 21:40:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 31-05-2014 / 19:53:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests methodsFor:'tests'!
+
+test_all_class_var_names
+    | class actualClassVars expectedClassVars |
+
+    class := model createClass
+        name: #MockClassForTestCase;
+        classVariableNames: #('ClassVar1' 'ClassVar2');
+        yourself.
+
+    expectedClassVars := (Object allClassVarNames, (Array with: #ClassVar1 with: #ClassVar2)).
+    actualClassVars := class theNonMetaclass allClassVarNames.
+
+    self assert: expectedClassVars = actualClassVars
+
+    "Created: / 20-06-2014 / 22:35:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 09-10-2014 / 10:47:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_at_class_found
+    | expectedClass actualClass |
+
+    expectedClass := model createClass
+        name: #DummyClass01;
+        compile;
+        yourself.
+
+    actualClass := model at: #DummyClass01.
+    
+    self assert: expectedClass = actualClass
+
+    "Modified: / 16-11-2014 / 17:08:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_at_class_missing
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+
+    actualClass := model at: #DummyClass01.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 16-11-2014 / 17:08:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_changes_empty_as_default
+
+    self assert: model changes size == 0
+
+    "Created: / 22-07-2014 / 22:52:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:23:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_and_class_method_generated_as_one_undo_change
+    | className class lastUndoChange |
+
+    lastUndoChange := self lastUndoChange.
+
+    className := #MockClassForTestingOneUndoChange.
+
+    self assertClassNotExists: className.
+
+    model := CustomNamespace new.
+    model changeManager: refactoryChangeManager.
+
+    class := model createClass
+        name: className;
+        compile;
+        yourself.  
+
+    self assertClassNotExists: className.
+
+    model createMethod
+        class: class theMetaclass;
+        protocol: 'a protocol';
+        source: 'aSelector
+        ^ nil';
+        compile.
+
+    self assertClassNotExists: className.
+    self assert: lastUndoChange = (self lastUndoChange).
+
+    model execute.
+
+    self assertClassExists: className.
+    self deny: lastUndoChange = (self lastUndoChange).
+    self assert: ((Smalltalk classNamed: className) class includesSelector: #aSelector).
+    self assert: ((Smalltalk classNamed: className) includesSelector: #aSelector) not.
+
+    refactoryChangeManager undoOperation.
+
+    self assertClassNotExists: className.
+    self assert: lastUndoChange = (self lastUndoChange).
+
+    "Created: / 17-04-2014 / 23:54:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 14:40:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_and_instance_method_generated_as_one_undo_change
+    | className class lastUndoChange |
+
+    lastUndoChange := self lastUndoChange.
+
+    className := #MockClassForTestingOneUndoChange.
+
+    self assertClassNotExists: className.
+
+    model := CustomNamespace new.
+    model changeManager: refactoryChangeManager.  
+
+    class := model createClass
+        name: className;
+        compile;
+        yourself.  
+
+    self assertClassNotExists: className.
+
+    model createMethod
+        class: class;
+        protocol: 'a protocol';
+        source: 'aSelector
+        ^ nil';
+        compile.
+
+    self assertClassNotExists: className.
+    self assert: lastUndoChange = (self lastUndoChange).
+
+    model execute.
+
+    self assertClassExists: className.
+    self deny: lastUndoChange = (self lastUndoChange).
+    self assert: ((Smalltalk classNamed: className) includesSelector: #aSelector).
+
+    refactoryChangeManager undoOperation.
+
+    self assertClassNotExists: className.
+    self assert: lastUndoChange = (self lastUndoChange).
+
+    "Created: / 17-04-2014 / 23:54:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 14:40:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_comment_in_method_generated
+    | class generatedSource expectedSource |
+
+    class := self class.
+
+    model createMethod
+        class: self class;
+        protocol: 'a protocol';
+        source: 'aSelector
+            "a comment"
+            ^ nil';
+        compile.
+
+    self assert: (class includesSelector: #aSelector) not.
+
+    model execute.
+
+    generatedSource := (class sourceCodeAt: #aSelector).
+    expectedSource := 'aSelector
+    "a comment"
+
+    ^ nil'.
+
+    self assert: (class includesSelector: #aSelector).
+    self assert: (generatedSource includesSubString: '"a comment"').
+    self assertSource: expectedSource sameAs: generatedSource
+
+    "Created: / 27-04-2014 / 15:57:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-08-2014 / 23:42:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-10-2014 / 23:06:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate
+    | mockClass |
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase'.
+
+    self assert: mockClass new className = 'MockClassForTestCase'.
+    self assert: mockClass superclass new className = 'Object'.
+    self assert: mockClass instanceVariableString = ''.
+    self assert: mockClass classVariableString = ''.
+    self assert: mockClass poolDictionaries = ''.
+    self assert: mockClass category = ''.
+
+    "Created: / 15-06-2014 / 17:27:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 27-07-2014 / 12:42:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_object_changes_kept
+    | expectedId actualId mockClass |
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase01'.
+    expectedId := mockClass identityHash.
+    mockClass package: #some_package.
+
+    model createClassImmediate: 'MockClassForTestCase02'.
+    self assertClassExists: #MockClassForTestCase02.  
+
+    actualId := (Smalltalk at: #MockClassForTestCase01) identityHash.
+
+    self assert: expectedId = actualId.
+    self assert: (Smalltalk at: #MockClassForTestCase01) package = #some_package.
+
+    "Created: / 02-11-2014 / 16:27:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_super_class_name_instance_variable_names_class_variable_names_pool_dictionaries_category_private_in_private_class
+    | mockClass |
+
+    mockClass := model
+        createClassImmediate: 'MockClassForTestCase' 
+        superClassName: 'Object'
+        instanceVariableNames: 'instVar'
+        classVariableNames: 'ClassVar'
+        poolDictionaries: 'pollDict01'
+        category: 'Some-Category01'
+        privateIn: 'Object'.
+
+    self assert: mockClass name = 'Object::MockClassForTestCase'.
+    self assert: mockClass superclass name = 'Object'.
+    self assert: mockClass instanceVariableString = 'instVar'.
+    self assert: mockClass classVariableString = 'ClassVar'.
+    self assert: mockClass poolDictionaries = 'pollDict01'.
+    self assert: mockClass category = Object category.
+    self assert: (mockClass owningClass name) = 'Object'.
+
+    "Modified: / 31-10-2014 / 00:19:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_super_class_name_private_in
+    | mockClass |
+
+    mockClass := model
+        createClassImmediate: 'MockClassForTestCase' 
+        superClassName: 'Object'
+        privateIn: 'Object'.
+
+    self assert: mockClass name = 'Object::MockClassForTestCase'.
+    self assert: mockClass superclass name = 'Object'.
+    self assert: mockClass instanceVariableString = ''.
+    self assert: mockClass classVariableString = ''.
+    self assert: mockClass poolDictionaries = ''.
+    self assert: mockClass category = Object category.
+    self assert: (mockClass owningClass name) = 'Object'.
+
+    "Modified: / 31-10-2014 / 00:20:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_category
+    | mockClass |
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' category: 'Some-Category01'.
+
+    self assert: mockClass new className = 'MockClassForTestCase'.
+    self assert: mockClass superclass new className = 'Object'.
+    self assert: mockClass instanceVariableString = ''.
+    self assert: mockClass classVariableString = ''.
+    self assert: mockClass poolDictionaries = ''.
+    self assert: mockClass category = 'Some-Category01'.
+
+    "Modified: / 19-10-2014 / 20:56:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_given_super_class_name
+    | mockClass |
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+
+    self assert: mockClass new className = 'MockClassForTestCase'.
+    self assert: mockClass superclass new className = 'Object'.
+    self assert: mockClass instanceVariableString = ''.
+    self assert: mockClass classVariableString = ''.
+    self assert: mockClass poolDictionaries = ''.
+    self assert: mockClass category = ''.
+
+    "Created: / 27-07-2014 / 12:42:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_instance_and_class_variables
+    | mockClass |
+
+    mockClass := model
+        createClassImmediate: 'MockClassForTestCase' 
+        superClassName: 'Object'
+        instanceVariableNames: 'instVar'
+        classVariableNames: 'ClassVar'.
+
+    self assert: mockClass new className = 'MockClassForTestCase'.
+    self assert: mockClass superclass new className = 'Object'.
+    self assert: mockClass instanceVariableString = 'instVar'.
+    self assert: mockClass classVariableString = 'ClassVar'.
+    self assert: mockClass poolDictionaries = ''.
+    self assert: mockClass category = ''.
+
+    "Created: / 23-08-2014 / 22:24:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_instance_variables
+    | mockClass |
+
+    mockClass := model
+        createClassImmediate: 'MockClassForTestCase' 
+        instanceVariableNames: 'instVar'.
+
+    self assert: mockClass new className = 'MockClassForTestCase'.
+    self assert: mockClass superclass new className = 'Object'.
+    self assert: mockClass instanceVariableString = 'instVar'.
+    self assert: mockClass classVariableString = ''.
+    self assert: mockClass poolDictionaries = ''.
+    self assert: mockClass category = ''.
+
+    "Created: / 23-08-2014 / 22:26:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_immediate_with_super_class_name_instance_variable_names_class_variable_names_pool_dictionaries_category    
+    | mockClass |
+
+    mockClass := model
+        createClassImmediate: 'MockClassForTestCase' 
+        superClassName: 'Object'
+        instanceVariableNames: 'instVar'
+        classVariableNames: 'ClassVar'
+        poolDictionaries: 'pollDict01'
+        category: 'Some-Category01'.
+
+    self assert: mockClass new className = 'MockClassForTestCase'.
+    self assert: mockClass superclass new className = 'Object'.
+    self assert: mockClass instanceVariableString = 'instVar'.
+    self assert: mockClass classVariableString = 'ClassVar'.
+    self assert: mockClass poolDictionaries = 'pollDict01'.
+    self assert: mockClass category = 'Some-Category01'.
+
+    "Modified (comment): / 19-10-2014 / 20:53:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_is_stored_in_model_when_compiled
+    | class classFromModel |
+
+    class := model createClass
+        name: #MockClassForTestCase;
+        compile;
+        yourself.
+
+    class compile: 'selector_01 ^ 1'.
+
+    classFromModel := model classNamed: #MockClassForTestCase.
+
+    self assert: class == classFromModel.
+    self assert: (classFromModel includesSelector: #selector_01).
+
+    "Created: / 03-11-2014 / 22:47:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_then_access_metaclass
+    | class |
+
+    class := model createClass.
+    class name: 'SomeClass'.
+    class superclassName: self class name.
+    "The compile method creates the change object and registers 
+    the class in the model (RBNamespace/CustomNamespace)"
+    class compile.
+
+    self assert: class theMetaClass notNil.
+    self assert: class theMetaClass theNonMetaClass == class
+
+    "Created: / 14-11-2014 / 23:53:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified (comment): / 19-11-2014 / 21:32:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_with_instance_variable
+    | expectedVariables actualVariables |
+
+    model createClass
+        name: #DummyClass01;
+        instanceVariableNames: (Array with: 'instanceVariable');
+        compile.
+
+    model execute.
+
+    expectedVariables := #('instanceVariable').
+    actualVariables := (Smalltalk at: #DummyClass01) instanceVariableNames.
+
+    self assert: expectedVariables = actualVariables
+
+    "Created: / 30-11-2014 / 19:11:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_with_name_as_string
+    | class |
+
+    class := model createClass
+        name: 'SomeClass';
+        superclassName: self class name;
+        compile;
+        yourself.
+
+    self assert: class == (model classNamed: #SomeClass).
+    self assert: class == (model classNamed: 'SomeClass').
+    self assert: (class theMetaclass) == (model metaclassNamed: #SomeClass).
+    self assert: (class theMetaclass) == (model metaclassNamed: 'SomeClass').
+
+    "Created: / 19-11-2014 / 21:02:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_with_superclass_name_as_string
+    | superclass |
+
+    model createClass
+        name: 'SomeClass';
+        superclassName: 'Object';
+        compile.
+
+    superclass := model classNamed: 'Object'.  
+
+    self assert: superclass == (model classNamed: #Object).
+    self assert: superclass == (model classNamed: 'Object').
+    self assert: (superclass theMetaclass) == (model metaclassNamed: #Object).
+    self assert: (superclass theMetaclass) == (model metaclassNamed: 'Object').
+
+    "Created: / 23-11-2014 / 21:15:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_within_given_package
+    | class package |
+
+    package := self class package.
+    self assert: package size > 3.
+
+    model createClass
+        name: #MockClassForTestCase;
+        package: package;
+        compile.
+
+    model execute.
+
+    class := Smalltalk classNamed: 'MockClassForTestCase'.
+
+    self assert: class new className = 'MockClassForTestCase'.
+    self assert: class superclass new className = 'Object'.
+    self assert: class instanceVariableString = ''.
+    self assert: class classVariableString = ''.
+    self assert: class poolDictionaries = ''.
+    self assert: class category = '** As yet undefined **'.
+    self assert: class package = package.
+
+    "Created: / 30-08-2014 / 20:35:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 09-10-2014 / 23:23:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_class_without_given_package
+    | class package |
+
+    package := self class package.
+    self assert: package size > 3.
+
+    model createClass
+        name: #MockClassForTestCase;
+        compile.
+
+    model execute.
+
+    class := Smalltalk classNamed: 'MockClassForTestCase'.
+
+    self assert: class new className = 'MockClassForTestCase'.
+    self assert: class superclass new className = 'Object'.
+    self assert: class instanceVariableString = ''.
+    self assert: class classVariableString = ''.
+    self assert: class poolDictionaries = ''.
+    self assert: class category = '** As yet undefined **'.
+    self deny: class package = package.
+
+    "Created: / 30-08-2014 / 20:57:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 14:41:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate
+    | mockClass expectedSource actualSource |
+
+    expectedSource := 'instanceMethod:aParam
+    ^ self'.
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+    model createMethodImmediate: mockClass protocol: 'a protocol' source: expectedSource.
+
+    actualSource := (mockClass sourceCodeAt: #instanceMethod:).
+
+    self assertSource: expectedSource sameAs: actualSource.
+    self assert: (mockClass compiledMethodAt: #instanceMethod:) category = 'a protocol'
+
+    "Created: / 15-06-2014 / 17:28:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-06-2014 / 21:59:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate_object_changes_kept
+    | expectedId actualId mockClass method |
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+    method := model createMethodImmediate: mockClass protocol: 'a protocol' source: 'selector_01 ^ 11'.
+    expectedId := method identityHash.
+    method package: #some_package.
+    model createMethodImmediate: mockClass protocol: 'a protocol' source: 'selector_02 ^ 22'.
+    actualId := (mockClass compiledMethodAt:#selector_01) identityHash.
+
+    self assert: expectedId = actualId.
+    self assert: ((mockClass compiledMethodAt:#selector_01) package) = #some_package.
+
+    "Created: / 02-11-2014 / 16:12:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate_protocol_source_package
+    | expectedSource actualSource mockClass |
+
+    expectedSource := 'instanceMethod:aParam
+    ^ self'.
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+    model createMethodImmediate: mockClass 
+        protocol: 'a protocol' 
+        source: expectedSource 
+        package: #some_package01.
+
+    actualSource := (mockClass sourceCodeAt: #instanceMethod:).
+
+    self assertSource: expectedSource sameAs: actualSource.
+    self assert: (mockClass compiledMethodAt: #instanceMethod:) category = 'a protocol'.    
+    self assert: (mockClass compiledMethodAt: #instanceMethod:) package = #some_package01.
+
+    "Modified: / 17-10-2014 / 10:02:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_immediate_with_preset_protocol
+    | mockClass expectedSource actualSource |
+
+    expectedSource := 'instanceMethod:aParam
+    ^ self'.
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+    model createMethodImmediate: mockClass source: expectedSource.
+
+    actualSource := (mockClass sourceCodeAt: #instanceMethod:).
+
+    self assertSource: expectedSource sameAs: actualSource.
+    self assert: (mockClass compiledMethodAt: #instanceMethod:) category = 'protocol'
+
+    "Created: / 23-08-2014 / 21:48:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_within_given_package
+    | mockClass package method |
+
+    package := self class package.
+    self assert: package size > 3.
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+    model createMethod
+        class: mockClass;
+        protocol: 'a protocol';
+        package: package;
+        source: 'selector ^ 123';
+        compile.
+
+    model execute.
+
+    method := (mockClass compiledMethodAt: #selector).
+
+    self assert: method package = package
+
+    "Created: / 30-08-2014 / 18:45:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 00:02:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_create_method_without_given_package
+    | mockClass package method |
+
+    package := self class package.
+    self assert: package size > 3.
+
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: 'Object'.
+    model createMethod
+        class: mockClass;
+        protocol: 'a protocol';
+        source: 'selector ^ 123';
+        compile.
+
+    model execute.
+
+    method := (mockClass compiledMethodAt: #selector).
+
+    self deny: method package = package.
+
+    "Created: / 30-08-2014 / 18:46:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 14:41:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_define_class_with_private_class
+    | expectedClass actualClass |
+
+    expectedClass := model createClass
+        name: #DummyClass01;
+        compile;
+        yourself.
+
+    model defineClass: 'DummyClass01 subclass:#DummyPrivate01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyClass01'.    
+
+    actualClass := (model classNamed: #'DummyClass01::DummyPrivate01') owningClass.   
+
+    self assert: expectedClass = actualClass
+
+    "Modified: / 25-01-2015 / 13:12:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_define_class_without_private_class
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.    
+
+    actualClass := (model classNamed: #DummyClass01) owningClass.   
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:51:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_empty_class_definition_string
+    | expectedDefinition actualDefinition |
+
+    expectedDefinition := 'Object subclass: #''Unknown Class''
+        instanceVariableNames: ''''
+        classVariableNames: ''''
+        poolDictionaries: ''''
+        category: ''** As yet undefined **'''.
+
+    actualDefinition := model createClass definitionString.                                     
+
+    self assertSource: expectedDefinition sameAs: actualDefinition.
+
+    "Created: / 10-10-2014 / 15:41:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_empty_class_in_changes
+
+    model createClass compile.
+    self assert:(model changes changesSize) = 1.
+
+    "Created: / 22-07-2014 / 22:22:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 15:48:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_namespace
+    
+    self assert: model isNamespace
+
+    "Modified: / 16-11-2014 / 17:09:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_source_builded
+    | method expectedSource actualSource |
+
+    method := model createMethod
+        source: '`@methodName
+    ^ `variableName';
+        replace: '`@methodName' with: #selector;
+        replace: '`variableName' with: 'aName';
+        yourself.
+
+    expectedSource := 'selector
+    ^ aName'.
+
+    actualSource := method newSource.
+
+    self assertSource: expectedSource sameAs: actualSource
+
+    "Created: / 18-05-2014 / 17:14:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-08-2014 / 23:40:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 15:56:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_source_builded_with_comment
+    | method buildedSource expectedSource |
+
+    method := model createMethod
+        source: '`@methodName
+
+    `"comment
+
+    ^ `variableName';
+        replace: '`@methodName' with: #selector;
+        replace: '`variableName' with: 'aName';
+        replace: '`"comment' with: '"a comment"';
+        yourself.
+
+    buildedSource := method newSource.
+    expectedSource := 'selector
+    "a comment"
+
+    ^ aName'.
+
+    self assertSource: expectedSource sameAs: buildedSource
+
+    "Created: / 19-05-2014 / 18:57:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 26-08-2014 / 23:55:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 15:56:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_source_with_original_formatting
+    | method originalSource actualSource expectedSource |
+
+    originalSource := 'methodName
+
+    `variableName do: [ each | each call ].'.
+
+    expectedSource := 'methodName
+
+    collection do: [ each | each call ].'.
+
+    model formatter: CustomNoneSourceCodeFormatter new.
+    method := model createMethod
+        source: originalSource;
+        replace: '`variableName' with: 'collection';
+        yourself.
+
+    actualSource := method newSource.
+
+    self assertSource: expectedSource sameAs: actualSource.
+
+    "Created: / 22-07-2014 / 23:04:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 15:57:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_nil_changes_not_in_change_collector
+
+    self should: [ 
+        model createMethod compile.
+    ] raise: Error.
+
+    self assert: model changes changesSize = 0.
+
+    "Created: / 22-07-2014 / 22:16:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 16:00:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_changed_class
+    |class|
+
+    model createNewClassFor: self class. "Actually creates class modification"
+
+    class := RBClass new
+        model: model;  
+        name: self class name;
+        yourself.
+
+    model putModelClass: class.  
+
+    self assert: class == (model classNamed: class name).
+
+    "Created: / 04-11-2014 / 00:50:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_changed_metaclass
+    |class|
+
+    model createNewClassFor: self class. "Actually creates class modification"
+
+    class := RBMetaclass new
+        model: model;  
+        name: self class name;
+        yourself.
+
+    model putModelClass: class.  
+
+    self assert: class == (model metaclassNamed: class name).
+
+    "Created: / 04-11-2014 / 01:10:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_new_class
+    |class|
+
+    class := RBClass new
+        model: model;  
+        name: #DummyClassForTestCase01;
+        superclassName: #Object;
+        instVarNames: #();
+        classVariableNames: #();
+        poolDictionaryNames: #();
+        yourself.
+
+    model defineClass: class definitionString.
+    model putModelClass: class.  
+
+    self assert: class == (model classNamed: #DummyClassForTestCase01).
+
+    "Created: / 04-11-2014 / 00:25:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_new_metaclass
+    |class metaclass|
+
+    class := RBClass new
+        model: model;  
+        name: #DummyClassForTestCase01;
+        superclassName: #Object;
+        instVarNames: #();
+        classVariableNames: #();
+        poolDictionaryNames: #();
+        yourself.
+
+    metaclass := RBMetaclass new
+        model: model;
+        name: #DummyClassForTestCase01;
+        yourself.
+
+    model defineClass: class definitionString.
+    model putModelClass: metaclass.  
+
+    self deny: class == (model metaclassNamed: #DummyClassForTestCase01).
+    self assert: metaclass == (model metaclassNamed: #DummyClassForTestCase01).
+
+    "Created: / 04-11-2014 / 00:31:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_put_model_class_undefined_error
+    |class|
+
+    class := RBClass new
+        name: #DummyClassForTestCase01.
+
+    self should: [ 
+        model putModelClass: class.  
+    ] raise: Error
+
+    "Modified (format): / 04-11-2014 / 00:22:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_undo_changes_for_multiple_executes
+    "Note: Methods createClassImmediate and createMethodImmediate have execute call inside"
+    
+    |mockSuperClassName mockClassName mockSuperClass|
+
+    mockSuperClassName := 'MockSuperClassForTestCase'.
+    mockClassName := 'MockClassForTestCase'.
+    mockSuperClass := model createClassImmediate:mockSuperClassName
+            superClassName:'Object'.
+    model createClassImmediate:mockClassName
+        superClassName:mockSuperClassName.
+    
+    "/ Instance method
+    
+    model 
+        createMethodImmediate:mockSuperClass
+        protocol:'instance-protocol'
+        source:'instanceMethod: aParam
+    self shouldImplement'.
+    
+    "/ Class method
+    
+    model 
+        createMethodImmediate:mockSuperClass class
+        protocol:'class-protocol'
+        source:'classMethod: aParam
+    self shouldImplement'.
+    self assertClassExists:mockSuperClassName.
+    self assertClassExists:mockClassName.
+    model undoChanges.
+    self assertClassNotExists:mockSuperClassName.
+    self assertClassNotExists:mockClassName.
+
+    "Created: / 15-06-2014 / 16:21:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-10-2014 / 14:57:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNamespaceTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNewClassGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,185 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomNewClassGenerator
+	instanceVariableNames:'newClassName'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomNewClassGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Template class for generators which needs to create a new class.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomNewClassGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+
+    ^ true
+
+    "Created: / 08-11-2014 / 16:50:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+
+    ^ aCustomPerspective isClassPerspective
+
+    "Created: / 08-11-2014 / 16:50:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+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 == CustomNewClassGenerator.
+! !
+
+!CustomNewClassGenerator methodsFor:'accessing'!
+
+newClassName
+    "Returns a name of the new class to be created."
+
+    ^ newClassName
+
+    "Created: / 08-11-2014 / 16:58:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 09-11-2014 / 01:20:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassName: aClassName
+    "see newClassName"
+
+    newClassName := aClassName.
+
+    "Created: / 08-11-2014 / 16:59:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 09-11-2014 / 01:20:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewClassGenerator methodsFor:'accessing - ui'!
+
+defaultClassName
+    "Returns class name which will be displayed in dialog input box"
+
+    self subclassResponsibility
+
+    "Created: / 08-11-2014 / 16:56:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 09-11-2014 / 01:21:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassNameLabel
+    "Returns a label of the dialog for the new class to be created"
+
+    self subclassResponsibility
+
+    "Created: / 08-11-2014 / 16:57:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 09-11-2014 / 01:22:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewClassGenerator methodsFor:'executing - private'!
+
+buildForClass: aClass
+    "Subclass can modify the newly created class in here"
+
+    self subclassResponsibility
+
+    "Created: / 08-11-2014 / 17:06:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 09-11-2014 / 01:24:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+buildInContext:aCustomContext
+    | class |
+
+    class := model createClass
+        name: self newClassName asSymbol;
+        yourself.
+
+    self buildForClass: class.
+
+    class compile.
+
+    self executeSubGeneratorOrRefactoringClasses: (Array 
+            with: CustomSubclassResponsibilityCodeGenerator
+        )
+        inContext: (CustomSubContext new
+            selectedClasses: (Array with: class);
+            yourself
+        )
+
+    "Created: / 08-11-2014 / 17:10:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-12-2014 / 18:13:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext: aCustomContext
+    | initialClassName counter |
+
+    initialClassName := self defaultClassName.
+    counter := 1.
+    [ (Smalltalk at: initialClassName asSymbol) notNil ] whileTrue:[ 
+        initialClassName := self defaultClassName , counter printString.
+        counter := counter + 1.
+    ].
+    newClassName := dialog 
+                        requestClassName: self newClassNameLabel 
+                        initialAnswer: self defaultClassName.
+
+    "Created: / 08-11-2014 / 17:01:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-11-2014 / 21:24:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomNewClassGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNewClassGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,149 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomNewClassGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomNewClassGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomNewClassGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    |generator|
+
+    generator := mock mockOf: CustomNewClassGenerator.
+    generator class compileMockMethod: 'description ^ ''some description''. '.
+    ^ generator
+
+    "Modified: / 09-11-2014 / 00:36:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewClassGeneratorTests methodsFor:'tests'!
+
+test_available_in_context
+    
+    self assert: (generatorOrRefactoring class availableInContext: context)
+
+    "Modified: / 09-11-2014 / 00:17:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+    
+    self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective)
+
+    "Modified (comment): / 09-11-2014 / 00:18:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract
+    
+    self assert: CustomNewClassGenerator isAbstract
+
+    "Modified (comment): / 09-11-2014 / 00:30:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_class_generated
+
+    generatorOrRefactoring
+        compileMockMethod: 'buildForClass: aClass ^ self';
+        newClassName: #DummyClass01.
+
+    generatorOrRefactoring executeInContext: context.  
+
+    self assertClassExists: #DummyClass01.
+
+    "Created: / 09-11-2014 / 00:32:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_class_generated_with_dialog
+
+    dialog := mock mockOf: CustomDialog.
+    dialog compileMockMethod: 'requestClassName: aLabel initialAnswer: anAnswer
+
+        self assert: aLabel = ''some label''.
+        self assert: anAnswer = ''DummyClass01''.
+
+        ^ anAnswer. '.
+
+    generatorOrRefactoring
+        compileMockMethod: 'buildForClass: aClass ^ aClass superclassName: CustomCodeGenerator name';
+        compileMockMethod: 'newClassNameLabel ^ ''some label''. ';
+        compileMockMethod: 'defaultClassName ^ ''DummyClass01''. ';
+        dialog: dialog.
+
+    context := CustomBrowserContext new.
+
+    generatorOrRefactoring executeInContext: context.  
+
+    self assertClassExists: #DummyClass01.
+
+    "Created: / 09-11-2014 / 00:48:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-11-2014 / 23:41:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:06:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_new_class_generated_with_subclass_responsibility
+    | expectedSource |
+
+    generatorOrRefactoring
+        compileMockMethod: 'buildForClass: aClass ^ aClass superclassName: CustomCodeGenerator name';
+        newClassName: #DummyClass01.
+
+    generatorOrRefactoring executeInContext: context.  
+
+    self assertClassExists: #DummyClass01.
+
+    expectedSource := 'buildInContext:aCustomContext
+    self shouldImplement'.
+
+    self assertMethodSource: expectedSource atSelector: #buildInContext: forClass: (Smalltalk at: #DummyClass01).
+
+    "Created: / 09-11-2014 / 00:41:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:06:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNewSystemBrowserTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,342 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomNewSystemBrowserTests
+	instanceVariableNames:'browser mock menu manager generatorClassMock'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-UI-Tests'
+!
+
+!CustomNewSystemBrowserTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomNewSystemBrowserTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    mock := CustomMock new.
+    menu := Menu labels: 'label' values: nil.
+    browser := (mock mockOf: Tools::NewSystemBrowser).
+    mock createMockGetters: browser class forSelectors: {
+        'information'. 'theSingleSelectedClass'. 'switchToClass'. 'selectProtocol'
+    }.
+    browser
+        compileMockMethod: 'information: aString
+            self objectAttributeAt: #information put: aString';
+        compileMockMethod: 'theSingleSelectedClass: aClass
+            self objectAttributeAt: #theSingleSelectedClass put: aClass';
+        compileMockMethod: 'createBuffer ^ true';
+        compileMockMethod: 'switchToClass: aClass
+            self objectAttributeAt: #switchToClass put: aClass';
+        compileMockMethod: 'selectProtocol: aProtocol
+            self objectAttributeAt: #selectProtocol put: aProtocol';
+        compileMockMethod: 'customMenuBuilder
+            | builder |
+
+            builder := super customMenuBuilder.
+            builder manager: (self objectAttributeAt: #manager).
+            ^ builder'.
+
+    manager := mock mockOf: Object.
+    manager compileMockMethod: 'generatorsAndRefactoringsSelect: aBlock
+        ^ self objectAttributeAt: #codeGenerators';
+        objectAttributeAt: #codeGenerators put: OrderedCollection new.  
+
+    browser objectAttributeAt: #manager put: manager.
+
+    generatorClassMock := mock mockClassOf: Object.
+    mock createMockGetters: generatorClassMock forSelectors: {'label'. 'group'}.
+
+    "Modified: / 24-01-2015 / 20:08:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    mock unmockAll.
+    
+    super tearDown.
+
+    "Modified: / 26-12-2014 / 19:17:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewSystemBrowserTests methodsFor:'private'!
+
+addGenerator: aLabel group: aGroup
+    "Creates initialized code generator mock and adds it to managers generators"
+    | generator |
+
+    generator := generatorClassMock new
+        objectAttributeAt: #label put: aLabel;
+        objectAttributeAt: #group put: aGroup;
+        yourself.
+
+    (manager objectAttributeAt: #codeGenerators) add: generator.
+
+    ^ generator
+
+    "Created: / 29-12-2014 / 08:51:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+menuItemLabels
+    "Helper which returns labels from menu item as collection as string.
+    We are comparing labels, because menu items are not comparable - 
+    MenuItem label: 'Label' not equals MenuItem label: 'Label'"
+
+    ^ (OrderedCollection streamContents: [ :stream |
+        menu itemsDo: [ :item |
+            stream nextPut: item label.
+            item submenuChannel notNil ifTrue: [ 
+                stream nextPut: (OrderedCollection streamContents: [ :innerStream |
+                    item submenuChannel value itemsDo: [ :innerItem |
+                        innerStream nextPut: innerItem label
+                    ]
+                ]) asArray
+            ]
+        ]
+    ]) asArray
+
+    "Created: / 29-12-2014 / 08:52:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewSystemBrowserTests methodsFor:'tests'!
+
+test_class_menu_extension_custom_generators
+    | expectedMenu actualMenu |
+
+    menu := Menu labels: 'Generate
+label' values: nil.
+
+    expectedMenu := {'Generate'. 'Generate - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #(Group).
+
+    browser classMenuExtensionCustomGenerators: menu.
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Created: / 29-12-2014 / 08:56:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_custom_refactorings
+    | expectedMenu actualMenu |
+
+    menu := Menu labels: 'Generate
+label' values: nil.
+
+    expectedMenu := {'Generate'. 'Refactor - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #(Group).
+
+    browser classMenuExtensionCustomRefactorings: menu.
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Created: / 29-12-2014 / 09:10:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_custom_extensions
+    | expectedClass actualClass |
+
+    expectedClass := CustomRBMethodTests.
+    browser theSingleSelectedClass: RBMethod.
+    browser classMenuExtensionNavigateToTestCase: menu.
+    menu lastItem itemValue value. "Call menu item action block"
+    actualClass := browser switchToClass.   
+
+    self assert: expectedClass = actualClass.
+    self assert: (browser selectProtocol) == #tests
+
+    "Created: / 26-12-2014 / 18:58:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-01-2015 / 19:53:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_found
+    | expectedClass actualClass |
+
+    expectedClass := CustomContextTests.
+    browser theSingleSelectedClass: CustomContext.
+    browser classMenuExtensionNavigateToTestCase: menu.
+    menu lastItem itemValue value. "Call menu item action block"
+    actualClass := browser switchToClass.
+
+    self assert: expectedClass = actualClass.
+    self assert: (browser selectProtocol) == #tests
+
+    "Created: / 26-12-2014 / 18:53:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_not_found
+    | expectedInformation actualInformation |
+
+    expectedInformation := 'Test Case named SmallSense::CustomNewSystemBrowserTestsTests not found'.
+    browser theSingleSelectedClass: CustomNewSystemBrowserTests.
+    browser classMenuExtensionNavigateToTestCase: menu.
+    menu lastItem itemValue value. "Call menu item action block"
+    actualInformation := browser information.
+
+    self assert: expectedInformation = actualInformation
+
+    "Created: / 26-12-2014 / 18:32:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:00:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_class_menu_extension_navigate_to_test_case_placed_after_generate
+    | expectedPosition actualPosition foundItem |
+
+    expectedPosition := 3.
+
+    menu := Menu labels: 'Label_01
+Generate
+Label_02' values: nil.
+
+    browser classMenuExtensionNavigateToTestCase: menu.
+    actualPosition := 0.
+    foundItem := false.
+    menu itemsDo: [ :item |  
+        foundItem ifFalse: [
+            actualPosition := actualPosition + 1.
+            foundItem := (item label = 'Open Test Case Class').
+        ]
+    ].
+
+    self assert: expectedPosition = actualPosition
+
+    "Created: / 26-12-2014 / 19:01:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_view_menu_extension_custom_refactorings
+    | expectedMenu actualMenu |
+
+    menu := Menu labels: 'Refactor
+label' values: nil.
+
+    expectedMenu := {'Refactor'. 'Refactor - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #(Group).
+
+    browser codeViewMenuExtensionCustomRefactorings: menu.
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Created: / 29-12-2014 / 09:16:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_menu_extension_custom_generators
+    | expectedMenu actualMenu |
+
+    menu := Menu labels: 'Generate
+label' values: nil.
+
+    expectedMenu := {'Generate'. 'Generate - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #(Group).
+
+    browser selectorMenuExtensionCustomGenerators: menu.
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Created: / 29-12-2014 / 09:18:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_menu_extension_custom_refactorings
+    | expectedMenu actualMenu |
+
+    menu := Menu labels: 'Refactor
+label' values: nil.
+
+    expectedMenu := {'Refactor'. 'Refactor - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #(Group).
+
+    browser selectorMenuExtensionCustomRefactorings: menu.
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Created: / 29-12-2014 / 09:26:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_variables_menu_extension_custom_generators
+    | expectedMenu actualMenu |
+
+    menu := Menu labels: 'Generate
+label' values: nil.
+
+    expectedMenu := {'Generate'. 'Generate - Custom'. {'Generator_01'. '-'. 'Generator_02'}. 'label'}.
+
+    self
+        addGenerator: 'Generator_01' group: #();
+        addGenerator: 'Generator_02' group: #(Group).
+
+    browser variablesMenuExtensionCustomGenerators: menu.
+    actualMenu := self menuItemLabels.
+
+    self assert: expectedMenu = actualMenu
+
+    "Created: / 29-12-2014 / 09:31:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNewSystemBrowserTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNoneSourceCodeFormatter.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,78 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomSourceCodeFormatter subclass:#CustomNoneSourceCodeFormatter
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomNoneSourceCodeFormatter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Should keep original source code formatting even after code replacements - see CustomSourceCodeGenerator.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomNoneSourceCodeFormatter methodsFor:'formatting'!
+
+formatParseTree:aParseTree
+    "Returns parse tree with (possibly) original/unchanged formatting"
+
+    aParseTree source isNil ifTrue:[
+        "no source - try to build from parse tree "
+        ^ aParseTree formattedCode
+    ] ifFalse: [
+        ^ aParseTree source
+    ]
+
+    "Modified: / 29-08-2014 / 22:26:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomNoneSourceCodeFormatterTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,102 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomNoneSourceCodeFormatterTests
+	instanceVariableNames:'formatter'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomNoneSourceCodeFormatterTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomNoneSourceCodeFormatterTests methodsFor:'initialization & release'!
+
+setUp
+
+    formatter := CustomNoneSourceCodeFormatter new
+
+    "Modified: / 31-08-2014 / 15:04:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNoneSourceCodeFormatterTests methodsFor:'tests'!
+
+test_format_parse_tree_source_is_nil
+    | expectedSource actualSource parseTree source |
+
+    source := 'selector ^ 777'.
+    parseTree := RBParser parseMethod: source.
+    parseTree source: nil.
+
+    actualSource := (formatter formatParseTree: parseTree) copyWithRegex: '\s' matchesReplacedWith: ''.    
+    expectedSource := 'selector^777'.
+
+    self assert: actualSource = expectedSource.
+
+    "Created: / 31-08-2014 / 15:06:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_format_parse_tree_source_not_nil
+    | expectedSource actualSource parseTree source |
+
+    source := 'selector ^ 777'.
+    parseTree := RBParser parseMethod: source.
+    parseTree source: source.
+
+    actualSource := formatter formatParseTree: parseTree.    
+    expectedSource := 'selector ^ 777'.
+
+    self assert: actualSource = expectedSource.
+
+    "Created: / 31-08-2014 / 15:07:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomNoneSourceCodeFormatterTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomParseTreeRewriter.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,137 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+ParseTreeSourceRewriter subclass:#CustomParseTreeRewriter
+	instanceVariableNames:'oldSource newSource'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomParseTreeRewriter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Extension for ParseTreeSourceRewriter so that it work even for expressions and not just methods.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomParseTreeRewriter methodsFor:'accessing'!
+
+executeTree: aParseTree
+    "Like ParseTreeSourceRewriter >> executeTree:, but with
+    additional support for expressions"
+    | oldContext treeFromRewrittenSource |
+
+    oldContext := context.
+    context := (RBSmallDictionary ? Dictionary) new.
+    answer := false.
+    oldSource isNil ifTrue: [
+        oldSource := aParseTree source
+    ].  
+
+    oldSource isNil ifTrue: [ 
+        self error: 'We need the oldSource string to be set'.
+    ].
+
+    "/Rewrite the tree as usual and then (try to) rewrite the original source code
+    tree := self visitNode: aParseTree.
+    replacements notNil ifTrue:[
+        newSource := self executeReplacementsInSource: oldSource.
+    ] ifFalse:[
+        ^answer
+    ].
+    "/DO NOT forget rewrites here!!!!!!"
+
+    "/Now, validates that rewritten parse tree is the same as
+    "/the one we get from the rewritten source:
+    aParseTree isMethod ifTrue: [ 
+        treeFromRewrittenSource := RBParser parseRewriteMethod: newSource onError:[:error :position|nil].
+    ] ifFalse: [ 
+        treeFromRewrittenSource := RBParser parseExpression: newSource onError:[:error :position|nil].
+    ].
+    treeFromRewrittenSource = tree ifTrue:[
+        (tree respondsTo: #source:) ifTrue: [ 
+            tree source: newSource.
+        ].
+    ] ifFalse: [
+        "Better set newSource to nil in order to indicate that something went wrong"
+        newSource := nil.
+    ].
+    context := oldContext.
+    ^answer
+
+    "Created: / 09-12-2014 / 21:16:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 22:07:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newSource
+    "Returns the source code string after the replacements were executed"
+
+    ^ newSource
+
+    "Modified (comment): / 09-12-2014 / 22:19:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+oldSource
+    "Returns custom old source code string - the code before replacements were made"
+
+    ^ oldSource
+
+    "Modified (comment): / 09-12-2014 / 21:19:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+oldSource: aString
+    "see oldSource"
+
+    oldSource := aString
+
+    "Modified (comment): / 09-12-2014 / 21:19:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomParseTreeRewriterTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,219 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomParseTreeRewriterTests
+	instanceVariableNames:'rewriter'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomParseTreeRewriterTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomParseTreeRewriterTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    rewriter := CustomParseTreeRewriter new
+
+    "Modified: / 10-12-2014 / 22:29:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomParseTreeRewriterTests methodsFor:'tests'!
+
+test_execute_tree_expression_01
+    | parseTree originalSource foundMatch expectedSource actualSource |
+
+    originalSource := 'condition ifTrue: [
+        self doStuff
+    ]'.
+
+    expectedSource := 'condition ifTrue: [
+        self doAnotherStuff
+    ]'.
+
+    parseTree := RBParser parseExpression: originalSource.
+
+    rewriter
+        oldSource: originalSource;  
+        replace: 'self doStuff' with: 'self doAnotherStuff'.
+
+    foundMatch := rewriter executeTree: parseTree.
+    self assert: foundMatch.
+
+    actualSource := rewriter newSource.
+
+    self assert: expectedSource = actualSource
+
+    "Modified: / 10-12-2014 / 22:40:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_expression_02
+    | parseTree originalSource foundMatch expectedSource actualSource |
+
+    originalSource := 'condition ifTrue: [
+        self doStuff
+    ]'.
+
+    expectedSource := '''a literal string'''.
+
+    parseTree := RBParser parseExpression: originalSource.
+
+    rewriter
+        oldSource: originalSource;  
+        replace: '`@something' with: ' ''a literal string'' '.
+
+    foundMatch := rewriter executeTree: parseTree.
+    self assert: foundMatch.
+
+    actualSource := rewriter newSource.
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 10-12-2014 / 22:42:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_expression_new_source_empty
+    | parseTree originalSource foundMatch actualSource |
+
+    originalSource := 'condition ifTrue: [
+        self doStuff
+    ]'.
+
+    parseTree := RBParser parseExpression: originalSource.
+
+    rewriter
+        oldSource: originalSource;  
+        replace: '`#literal' with: ' ''a literal string'' '.
+
+    foundMatch := rewriter executeTree: parseTree.
+    self deny: foundMatch.
+
+    actualSource := rewriter newSource.
+
+    self assert: actualSource isNil
+
+    "Created: / 10-12-2014 / 22:46:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:20:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_expression_old_source_error
+    | parseTree originalSource |
+
+    originalSource := 'condition ifTrue: [
+        self doStuff
+    ]'.
+
+    parseTree := RBParser parseExpression: originalSource.
+
+    rewriter replace: '`@something' with: ' ''a literal string'' '.
+
+    self should: [ 
+        rewriter executeTree: parseTree.
+    ] raise: Error
+
+    "Created: / 10-12-2014 / 22:45:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:20:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_method_01
+    | parseTree originalSource foundMatch expectedSource actualSource |
+
+    originalSource := 'method: arg01
+    arg01 isSomething ifTrue: [
+        self doStuff
+    ]'.
+
+    expectedSource := 'method: arg01
+    arg01 isSomething ifTrue: [
+        self doAnotherStuff
+    ]'.
+
+    parseTree := RBParser parseMethod: originalSource.
+
+    rewriter
+        oldSource: originalSource;  
+        replace: 'self doStuff' with: 'self doAnotherStuff'.
+
+    foundMatch := rewriter executeTree: parseTree.
+    self assert: foundMatch.
+
+    actualSource := rewriter newSource.
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 10-12-2014 / 22:49:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_tree_method_02
+    | parseTree originalSource foundMatch expectedSource actualSource |
+
+    originalSource := 'method: arg01
+    arg01 isSomething ifTrue: [
+        self doStuff
+    ]'.
+
+    expectedSource := 'method: arg01
+    arg01 isAnotherThing ifTrue: [
+        self doAnotherStuff
+    ]'.
+
+    parseTree := RBParser parseMethod: originalSource.
+
+    rewriter
+        replace: '`@receiver isSomething' with: '`@receiver isAnotherThing';
+        replace: 'self doStuff' with: 'self doAnotherStuff'.
+
+    foundMatch := rewriter executeTree: parseTree.
+    self assert: foundMatch.
+
+    actualSource := rewriter newSource.
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 10-12-2014 / 22:53:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomPerspective.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,341 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomPerspective
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+CustomPerspective class instanceVariableNames:'theOneAndOnlyInstance'
+
+"
+ No other class instance variables are inherited by this class.
+"
+!
+
+CustomPerspective subclass:#Class
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#ClassCategory
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#CodeView
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#InstanceVariable
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Method
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Namespace
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Package
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+CustomPerspective subclass:#Protocol
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomPerspective
+!
+
+!CustomPerspective class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Represents a perspective marker from which is pop-up menu invoked.
+
+    When we select for example some class from the class menu in the Browser
+    (the STX IDE) then method isClassPerspective should return true and other
+    perspectives should return false.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz> 
+
+"
+! !
+
+!CustomPerspective class methodsFor:'instance creation'!
+
+flushSingleton
+    "flushes the cached singleton"
+
+    theOneAndOnlyInstance := nil
+
+    "
+     self flushSingleton
+    "
+!
+
+instance
+    "returns a singleton"
+
+    theOneAndOnlyInstance isNil ifTrue:[
+        theOneAndOnlyInstance := self basicNew initialize.
+    ].
+    ^ theOneAndOnlyInstance.
+
+    "Created: / 26-01-2014 / 10:57:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+new
+    "returns a singleton"
+
+    ^ self instance.
+
+    "Modified: / 26-01-2014 / 10:57:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective class methodsFor:'accessing'!
+
+classCategoryPerspective
+    ^ CustomPerspective::ClassCategory instance
+
+    "Created: / 14-10-2014 / 10:11:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classPerspective
+    ^ CustomPerspective::Class instance
+
+    "Created: / 26-01-2014 / 10:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+codeViewPerspective
+    ^ CustomPerspective::CodeView instance
+
+    "Created: / 14-10-2014 / 10:17:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+instanceVariablePerspective
+    ^ CustomPerspective::InstanceVariable instance
+
+    "Created: / 26-01-2014 / 11:00:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+methodPerspective
+    ^ CustomPerspective::Method instance
+
+    "Created: / 24-08-2014 / 11:14:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+namespacePerspective
+    ^ CustomPerspective::Namespace instance
+
+    "Created: / 14-10-2014 / 10:18:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+packagePerspective
+    ^ CustomPerspective::Package instance
+
+    "Created: / 14-10-2014 / 10:18:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+protocolPerspective
+    ^ CustomPerspective::Protocol instance
+
+    "Created: / 14-10-2014 / 10:18:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CustomPerspective
+
+    "Created: / 26-01-2014 / 10:58:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective methodsFor:'testing'!
+
+isClassCategoryPerspective
+    ^ false
+
+    "Created: / 14-10-2014 / 09:33:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isClassPerspective
+    ^ false
+
+    "Created: / 26-01-2014 / 13:10:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCodeViewPerspective
+    ^ false
+
+    "Created: / 14-10-2014 / 09:30:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isInstanceVariablePerspective
+    ^ false
+
+    "Created: / 26-01-2014 / 13:10:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isMethodPerspective
+    ^ false
+
+    "Created: / 24-08-2014 / 11:12:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isNamespacePerspective
+    ^ false
+
+    "Created: / 14-10-2014 / 09:32:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isPackagePerspective
+    ^ false
+
+    "Created: / 14-10-2014 / 09:32:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+isProtocolPerspective
+    ^ false
+
+    "Created: / 14-10-2014 / 09:29:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Class methodsFor:'testing'!
+
+isClassPerspective
+    ^ true
+
+    "Created: / 26-01-2014 / 13:10:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective::ClassCategory methodsFor:'testing'!
+
+isClassCategoryPerspective
+    ^ true
+
+    "Created: / 14-10-2014 / 10:09:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::CodeView methodsFor:'testing'!
+
+isCodeViewPerspective
+    ^ true
+
+    "Created: / 14-10-2014 / 10:10:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::InstanceVariable methodsFor:'testing'!
+
+isInstanceVariablePerspective
+    ^ true
+
+    "Created: / 26-01-2014 / 13:10:29 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Method methodsFor:'testing'!
+
+isMethodPerspective
+    ^ true
+
+    "Created: / 24-08-2014 / 11:13:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Namespace methodsFor:'testing'!
+
+isNamespacePerspective
+    ^ true
+
+    "Created: / 14-10-2014 / 10:10:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Package methodsFor:'testing'!
+
+isPackagePerspective
+    ^ true
+
+    "Created: / 14-10-2014 / 10:10:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective::Protocol methodsFor:'testing'!
+
+isProtocolPerspective
+    ^ true
+
+    "Created: / 14-10-2014 / 10:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPerspective class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomPerspectiveTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,230 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomPerspectiveTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomPerspectiveTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomPerspectiveTests methodsFor:'tests'!
+
+test_all_perspectives_false_as_default
+    | perspective |
+
+    perspective := CustomPerspective new.
+
+    self deny: perspective isClassCategoryPerspective.
+    self deny: perspective isClassPerspective.
+    self deny: perspective isCodeViewPerspective.
+    self deny: perspective isInstanceVariablePerspective.
+    self deny: perspective isMethodPerspective.
+    self deny: perspective isNamespacePerspective.
+    self deny: perspective isPackagePerspective.
+    self deny: perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:47:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_category_perspective
+    |perspective|
+
+    perspective := CustomPerspective classCategoryPerspective.
+    self assert:perspective isClassCategoryPerspective.
+    self deny:perspective isClassPerspective.
+    self deny:perspective isCodeViewPerspective.
+    self deny:perspective isInstanceVariablePerspective.
+    self deny:perspective isMethodPerspective.
+    self deny:perspective isNamespacePerspective.
+    self deny:perspective isPackagePerspective.
+    self deny:perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:49:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_perspective
+    |perspective|
+
+    perspective := CustomPerspective classPerspective.
+    self deny:perspective isClassCategoryPerspective.
+    self assert:perspective isClassPerspective.
+    self deny:perspective isCodeViewPerspective.
+    self deny:perspective isInstanceVariablePerspective.
+    self deny:perspective isMethodPerspective.
+    self deny:perspective isNamespacePerspective.
+    self deny:perspective isPackagePerspective.
+    self deny:perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:50:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_code_view_perspective
+    | perspective |
+
+    perspective := CustomPerspective codeViewPerspective.
+
+    self deny: perspective isClassCategoryPerspective.
+    self deny: perspective isClassPerspective.
+    self assert: perspective isCodeViewPerspective.
+    self deny: perspective isInstanceVariablePerspective.
+    self deny: perspective isMethodPerspective.
+    self deny: perspective isNamespacePerspective.
+    self deny: perspective isPackagePerspective.
+    self deny: perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:51:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_instance_variable_perspective
+    | perspective |
+
+    perspective := CustomPerspective instanceVariablePerspective.
+
+    self deny: perspective isClassCategoryPerspective.
+    self deny: perspective isClassPerspective.
+    self deny: perspective isCodeViewPerspective.
+    self assert: perspective isInstanceVariablePerspective.
+    self deny: perspective isMethodPerspective.
+    self deny: perspective isNamespacePerspective.
+    self deny: perspective isPackagePerspective.
+    self deny: perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:54:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract
+
+    self assert: CustomPerspective isAbstract.
+
+    "Created: / 14-10-2014 / 11:57:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_variable_perspective
+    | perspective |
+
+    perspective := CustomPerspective methodPerspective.
+
+    self deny: perspective isClassCategoryPerspective.
+    self deny: perspective isClassPerspective.
+    self deny: perspective isCodeViewPerspective.
+    self deny: perspective isInstanceVariablePerspective.
+    self assert: perspective isMethodPerspective.
+    self deny: perspective isNamespacePerspective.
+    self deny: perspective isPackagePerspective.
+    self deny: perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:54:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_namespace_perspective
+    | perspective |
+
+    perspective := CustomPerspective namespacePerspective.
+
+    self deny: perspective isClassCategoryPerspective.
+    self deny: perspective isClassPerspective.
+    self deny: perspective isCodeViewPerspective.
+    self deny: perspective isInstanceVariablePerspective.
+    self deny: perspective isMethodPerspective.
+    self assert: perspective isNamespacePerspective.
+    self deny: perspective isPackagePerspective.
+    self deny: perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:55:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_perspective
+    | perspective |
+
+    perspective := CustomPerspective packagePerspective.
+
+    self deny: perspective isClassCategoryPerspective.
+    self deny: perspective isClassPerspective.
+    self deny: perspective isCodeViewPerspective.
+    self deny: perspective isInstanceVariablePerspective.
+    self deny: perspective isMethodPerspective.
+    self deny: perspective isNamespacePerspective.
+    self assert: perspective isPackagePerspective.
+    self deny: perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:56:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_protocol_perspective
+    | perspective |
+
+    perspective := CustomPerspective protocolPerspective.
+
+    self deny: perspective isClassCategoryPerspective.
+    self deny: perspective isClassPerspective.
+    self deny: perspective isCodeViewPerspective.
+    self deny: perspective isInstanceVariablePerspective.
+    self deny: perspective isMethodPerspective.
+    self deny: perspective isNamespacePerspective.
+    self deny: perspective isPackagePerspective.
+    self assert: perspective isProtocolPerspective.
+
+    "Created: / 14-10-2014 / 11:56:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_singleton
+    | perspective_01 perspective_02 |
+
+    perspective_01 := CustomPerspective new.
+    perspective_02 := CustomPerspective new.
+
+    self assert: perspective_01 == perspective_02.
+
+    CustomPerspective flushSingleton.
+    perspective_02 := CustomPerspective new.
+
+    self deny: perspective_01 == perspective_02.
+
+    "Created: / 14-10-2014 / 12:01:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomPrintCodeSelectionRefactoring.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,82 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeSelectionRefactoring subclass:#CustomPrintCodeSelectionRefactoring
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomPrintCodeSelectionRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomPrintCodeSelectionRefactoring class methodsFor:'accessing-presentation'!
+
+description
+
+    ^ 'Wraps selected source code with Transcript showCR: to be printed out'
+
+    "Modified: / 15-11-2014 / 16:21:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+
+    ^ 'Wrap with Transcript showCR: '
+
+    "Modified: / 15-11-2014 / 16:21:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomPrintCodeSelectionRefactoring methodsFor:'executing - private'!
+
+buildInContext:aCustomContext
+
+    refactoryBuilder 
+          replace:'`@expression'
+          with:'(Transcript showCR: (`@expression) asString)'
+          inContext:aCustomContext
+
+    "Modified: / 15-11-2014 / 16:36:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBAbstractClassTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,1187 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBAbstractClassTests
+	instanceVariableNames:'rbClass mock model'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBAbstractClassTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Test extensions in RBAbstractClass.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomRBAbstractClassTests methodsFor:'initialization & release'!
+
+setUp
+
+    mock := CustomMock new.
+    model := CustomNamespace new.
+    model changeManager: CustomLocalChangeManager new.  
+    rbClass := mock mockOf: RBAbstractClass.
+    rbClass model: model.
+
+    "Created: / 30-09-2014 / 19:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 02-02-2015 / 22:43:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    model changeManager undoChanges.
+    mock unmockAll
+
+    "Created: / 30-09-2014 / 19:44:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 02-02-2015 / 22:43:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBAbstractClassTests methodsFor:'tests'!
+
+test_all_class_var_names_empty
+    | expectedClassVars actualClassVars |
+
+    rbClass compileMockMethod: 'allClassVariableNames ^ nil'.  
+
+    expectedClassVars := #().
+    actualClassVars := rbClass allClassVarNames.
+    
+    self assert: expectedClassVars = actualClassVars
+
+    "Created: / 30-09-2014 / 19:40:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_class_var_names_not_empty
+    | expectedClassVars actualClassVars |
+
+    rbClass compileMockMethod: 'allClassVariableNames ^ #(''C1'' ''C2'')'.  
+
+    expectedClassVars := #('C1' 'C2').
+    actualClassVars := rbClass allClassVarNames.
+    
+    self assert: expectedClassVars = actualClassVars
+
+    "Created: / 30-09-2014 / 19:47:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_for_object
+    | expectedClassNames actualClassNames |
+
+    rbClass := model classNamed: #Object.  
+
+    expectedClassNames := OrderedCollection new.
+    actualClassNames := OrderedCollection new.
+    rbClass allSuperclassesDo: [ :class |
+        actualClassNames add: class name
+    ].
+
+    self assert: expectedClassNames = actualClassNames
+
+    "Created: / 04-10-2014 / 13:21:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-10-2014 / 23:29:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_for_object_superclass
+    | expectedClassNames actualClassNames |
+
+    rbClass 
+        name: #SomeClass;
+        superclass: (model classNamed: #Object).  
+
+    expectedClassNames := OrderedCollection new add: #Object; yourself.
+    actualClassNames := OrderedCollection new.
+    rbClass allSuperclassesDo: [ :class |
+        actualClassNames add: class name
+    ].
+
+    self assert: expectedClassNames = actualClassNames
+
+    "Created: / 04-10-2014 / 23:28:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_with_real_class
+    | expectedClassNames actualClassNames realClass |
+
+    "This actually creates realclass"
+    realClass := mock mockClassOf: Object.
+
+    rbClass 
+        name: #SomeClass;
+        superclass: (model classNamed: realClass name asSymbol).  
+
+    expectedClassNames := OrderedCollection new 
+        add: realClass name asSymbol;
+        add: #Object;
+        yourself.
+
+    actualClassNames := OrderedCollection new.
+    rbClass allSuperclassesDo: [ :class |
+        actualClassNames add: class name
+    ].
+
+    self assert: expectedClassNames = actualClassNames
+
+    "Created: / 04-10-2014 / 23:44:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_all_superclasses_do_with_two_superclasses
+    | expectedClassNames actualClassNames superclass |
+
+    superclass := RBClass new 
+        name: #SomeClass_01;
+        superclass: (model classNamed: #Object);
+        yourself.
+
+    rbClass 
+        name: #SomeClass_02;
+        superclass: superclass.  
+
+    expectedClassNames := OrderedCollection new 
+        add: #SomeClass_01;
+        add: #Object;
+        yourself.
+
+    actualClassNames := OrderedCollection new.
+    rbClass allSuperclassesDo: [ :class |
+        actualClassNames add: class name
+    ].
+
+    self assert: expectedClassNames = actualClassNames
+
+    "Created: / 04-10-2014 / 23:38:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_method_with_all_filled
+    | method compiledMethod change |
+
+    rbClass compileMockMethod: 'isMeta ^ false'.
+
+    method := RBMethod new
+        source: 'selector_01 ^ `#literal';
+        protocol: 'a test protocol';
+        package: 'some_package';
+        model: model;
+        class: self class;
+        method: (self class compiledMethodAt: #test_compile_method_with_all_filled);
+        sourceCodeGenerator: (CustomSourceCodeGenerator new
+            formatter: CustomNoneSourceCodeFormatter new;
+            yourself);
+        replace: '`#literal' with: '1';
+        selector: #selector_01;
+        yourself.
+
+    change := rbClass compileMethod: method.
+
+    self assert: (rbClass includesSelector: #selector_01).
+
+    self assert: 'a test protocol' = (change protocol).
+    self assert: 'some_package' = (change package).
+    self assert: 'selector_01 ^ 1' = (change source).
+
+    compiledMethod := rbClass compiledMethodAt: #selector_01.
+
+    self assert: 'a test protocol' = (compiledMethod protocol).
+    self assert: 'some_package' = (compiledMethod package).
+    self assert: 'selector_01 ^ 1' = (compiledMethod source).
+
+    "Created: / 10-10-2014 / 12:17:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_method_with_real_method
+    | method compiledMethod realMethod change class |
+
+    rbClass compileMockMethod: 'isMeta ^ false'.
+
+    class := mock mockClassOf: Object.
+    class new compileMockMethod: 'selector_01 ^ 1'.
+    realMethod := class compiledMethodAt: #selector_01.  
+
+    method := RBMethod 
+        for: rbClass 
+        fromMethod: realMethod
+        andSelector: #selector_01.
+
+    change := rbClass compileMethod: method.
+
+    self assert: (rbClass includesSelector: #selector_01).
+
+    self assert: (realMethod category) = (change protocol).
+    self assert: (realMethod package) = (change package).
+    self assert: 'selector_01 ^ 1' = (change source).
+
+    compiledMethod := rbClass compiledMethodAt: #selector_01.
+
+    self assert: (realMethod category) = (compiledMethod protocol).
+    self assert: (realMethod package) = (compiledMethod package).
+    self assert: 'selector_01 ^ 1' = (compiledMethod source).
+
+    "Created: / 10-10-2014 / 13:20:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_method_with_source
+    | method change expectedSource actualSource |
+
+    rbClass compileMockMethod: 'isMeta ^ false'.
+
+    method := RBMethod new
+        source: 'selector_01 ^ 1';
+        yourself.
+
+    expectedSource := 'selector_01 ^ 1'.
+    change := rbClass compileMethod: method.
+
+    self assert: expectedSource = (change source).
+
+    actualSource := (rbClass compiledMethodAt: #selector_01) source.
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 10-10-2014 / 11:56:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_default
+    
+    self assert: Compiler == (rbClass compilerClass)
+
+    "Created: / 16-11-2014 / 16:44:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_java
+    | expectedCompiler actualCompiler |
+
+    rbClass realClass: JavaLanguage new.
+
+    expectedCompiler := JavaCompiler ? JavaCompilerForSmalltalkExtensionsOnly.
+    actualCompiler := rbClass compilerClass.
+    
+    self assert: expectedCompiler = actualCompiler
+
+    "Created: / 16-11-2014 / 16:45:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_javascript
+    | expectedCompiler actualCompiler |
+
+    rbClass realClass: STXJavaScriptLanguage new.
+
+    expectedCompiler := JavaScriptCompiler.
+    actualCompiler := rbClass compilerClass.
+    
+    self assert: expectedCompiler = actualCompiler
+
+    "Created: / 16-11-2014 / 16:54:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_smalltalk
+
+    rbClass realClass: self class.
+    
+    self assert: Compiler == (rbClass compilerClass)
+
+    "Created: / 16-11-2014 / 16:44:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_with_empty_real_class
+    | expectedCompiler actualCompiler |
+
+    expectedCompiler := Object compilerClass.
+    actualCompiler := rbClass compilerClass.
+    
+    self assert: expectedCompiler = actualCompiler
+
+    "Created: / 15-11-2014 / 17:02:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:20:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiler_class_with_filled_real_class
+    | expectedCompiler actualCompiler |
+
+    expectedCompiler := JavaClass compilerClass.
+
+    rbClass realClass: JavaClass.  
+    actualCompiler := rbClass compilerClass.
+    
+    self assert: expectedCompiler = actualCompiler
+
+    "Created: / 15-11-2014 / 17:02:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:22:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inherits_from_model_class
+    | class |
+
+    class := model classNamed: #Object.
+    rbClass
+        name: #SomeTestClass01;
+        superclassName: #Object.
+
+    self assert: (rbClass inheritsFrom: class).
+
+    "Created: / 11-10-2014 / 01:09:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 13-10-2014 / 20:47:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_model_class
+    |expectedMethods actualMethods|
+
+    rbClass
+        compileMockMethod:'isMeta ^ false';
+        compileMockMethod:'theNonMetaclass ^ self';
+        compileMockMethod:'theMetaclass ^ RBMetaclass new'.
+
+    rbClass
+        name:#SomeClass;
+        superclassName:#Object;
+        compile:'selector_01 ^ 1'.
+
+    expectedMethods := OrderedCollection new
+        add:(rbClass compiledMethodAt:#'selector_01');
+        yourself.
+
+    actualMethods := OrderedCollection new.
+
+    rbClass instAndClassMethodsDo:[ :method | 
+        actualMethods add:method 
+    ].
+
+    self assert:expectedMethods = actualMethods
+
+    "Created: / 01-11-2014 / 21:48:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 02-11-2014 / 10:44:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_model_subclass_class
+    |expectedMethods actualMethods|
+
+    rbClass := RBClass new
+        model:model;
+        name:#SomeClass;
+        superclassName:#Object;
+        classVariableNames:#();
+        poolDictionaryNames:#();
+        compile;
+        compile:'selector_01 ^ 1';
+        yourself.
+
+    expectedMethods := OrderedCollection new
+        add:(rbClass compiledMethodAt:#'selector_01');
+        yourself.
+
+    actualMethods := OrderedCollection new.
+
+    rbClass instAndClassMethodsDo:[ :method | 
+        actualMethods add:method 
+    ].
+
+    self assert:expectedMethods = actualMethods
+
+    "Created: / 02-11-2014 / 10:30:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_model_subclass_class_and_metaclass
+    |expectedMethods actualMethods|
+
+    rbClass := RBClass new
+        model:model;
+        name:#SomeClass;
+        superclassName:#Object;
+        classVariableNames:#();
+        poolDictionaryNames:#();
+        compile;
+        compile:'selector_01 ^ 1';
+        yourself.
+
+    rbClass theMetaclass compile:'selector_02 ^ 2'.
+
+    expectedMethods := OrderedCollection new
+        add:(rbClass compiledMethodAt:#'selector_01');
+        add:(rbClass theMetaclass compiledMethodAt:#'selector_02');
+        yourself.
+
+    actualMethods := OrderedCollection new.
+
+    rbClass instAndClassMethodsDo:[ :method | 
+        actualMethods add:method 
+    ].
+
+    self assert:expectedMethods = actualMethods
+
+    "Created: / 02-11-2014 / 10:41:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_inst_and_class_methods_do_with_real_class
+    |actualSelectors realClass|
+
+    realClass := model classNamed: self class name.  
+
+    actualSelectors := OrderedCollection new.
+
+    realClass instAndClassMethodsDo:[ :method | 
+        actualSelectors add:method selector
+    ].
+
+    "class method"
+    self assert: (actualSelectors includes:#test_inst_and_class_methods_do_with_real_class).
+
+    "metaclass method"
+    self assert: (actualSelectors includes:#documentation).
+    self deny: (self class includesSelector:#documentation). "to be sure that its just in metaclass"
+
+    "Created: / 02-11-2014 / 11:05:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_custom_value_false
+
+    rbClass := model createClass
+        name: #DummyClass;
+        compile;
+        isAbstract: false;
+        yourself.
+    
+    self deny: rbClass isAbstract
+
+    "Created: / 14-12-2014 / 17:03:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-12-2014 / 18:03:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_custom_value_true
+
+    rbClass := model createClass
+        name: #DummyClass;
+        compile;
+        isAbstract: true;
+        yourself.
+    
+    self assert: rbClass isAbstract
+
+    "Created: / 14-12-2014 / 17:02:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-12-2014 / 18:03:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_default_value_for_new_class
+    
+    self assert: rbClass isAbstract
+
+    "Created: / 14-12-2014 / 17:01:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_guess_from_method
+
+    rbClass
+        compileMockMethod: 'isMeta ^ false';
+        compile: 'selector_01 ^ self subclassResponsibility'.
+    
+    self assert: rbClass isAbstract.
+    self assert: (rbClass whichSelectorsReferToSymbol: #subclassResponsibility) notEmptyOrNil
+
+    "Created: / 14-12-2014 / 17:04:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_guess_from_my_name_referenced
+
+    "We need some reference outside the class itself"
+    model createClass
+        name: #DummyClass01;
+        compile;
+        compile: 'selector_01 ^ DummyClass02 new'.
+
+    rbClass
+        compileMockMethod: 'isMeta ^ false';
+        name: #DummyClass02.
+    
+    self deny: rbClass isAbstract.
+
+    "Created: / 14-12-2014 / 17:10:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_abstract_set_for_both_class_and_metaclass
+
+    rbClass := model createClass
+        name: 'DummyClass';
+        compile;
+        isAbstract: false;
+        yourself.
+    
+    self deny: (rbClass theMetaclass isAbstract).
+    self deny: (rbClass theNonMetaclass isAbstract).
+
+    rbClass isAbstract: true.
+
+    self assert: (rbClass theMetaclass isAbstract).
+    self assert: (rbClass theNonMetaclass isAbstract).
+
+    "Created: / 14-12-2014 / 17:44:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_loaded
+
+    self assert: rbClass isLoaded
+
+    "Created: / 15-11-2014 / 17:12:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_model_class
+    | class |
+
+    class := model classNamed: #Object.
+
+    rbClass
+        name: #SomeTestClass01;
+        superclassName: #Object.
+
+    self assert: (rbClass isSubclassOf: class).
+
+    "Created: / 11-10-2014 / 00:57:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_model_class_not_found
+    | class |
+
+    class := RBClass new
+        name: #SomeTestClass02;
+        yourself.
+
+    rbClass
+        name: #SomeTestClass01;
+        superclassName: #Object.
+
+    self deny: (rbClass isSubclassOf: class).
+
+    "Created: / 11-10-2014 / 12:22:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_model_class_two_level_subclass
+    | class |
+
+    class := model classNamed: #Object.
+
+    rbClass
+        name: #SomeTestClass01;
+        superclass: (RBClass new
+            name: #SomeTestClass02;
+            model: model;
+            superclassName: #Object;
+            yourself).
+
+    self assert: (rbClass isSubclassOf: class).
+
+    "Created: / 11-10-2014 / 01:06:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_real_class
+    | class |
+
+    class := Object.
+
+    rbClass
+        name: #SomeTestClass01;
+        superclassName: #Object.
+
+    self assert: (rbClass isSubclassOf: class).
+
+    "Created: / 11-10-2014 / 01:00:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_subclass_of_real_class_two_level_subclass
+    | class |
+
+    class := Object.
+
+    rbClass
+        name: #SomeTestClass01;
+        superclass: (RBClass new
+            name: #SomeTestClass02;
+            model: model;
+            superclassName: #Object;
+            yourself).
+
+    self assert: (rbClass isSubclassOf: class).
+
+    "Created: / 11-10-2014 / 01:05:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_add_and_remove_methods
+    | expectedMethodDictionary actualMethodDictionary expectedMethodDictionaryKeys actualMethodDictionaryKeys |
+
+    rbClass compileMockMethod: 'isMeta ^ false'.
+
+    expectedMethodDictionary := MethodDictionary 
+        withKeys: (Array with: #selector_01 with: #selector_03) 
+        andValues: (Array with: Method new with: Method new).
+
+    rbClass
+        compile: 'selector_01 ^ 1';
+        compile: 'selector_02 ^ 2';
+        compile: 'selector_03 ^ 3';
+        removeMethod: #selector_02.
+
+    actualMethodDictionary := rbClass methodDictionary.
+    expectedMethodDictionaryKeys := expectedMethodDictionary keys asSortedCollection.
+    actualMethodDictionaryKeys := actualMethodDictionary keys asSortedCollection.
+    
+    self assert: expectedMethodDictionaryKeys = actualMethodDictionaryKeys
+
+    "Created: / 30-09-2014 / 20:02:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-09-2014 / 21:54:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_add_and_remove_methods_source
+    | expectedMethodDictionarySources actualMethodDictionarySources |
+
+    rbClass
+        compileMockMethod: 'isMeta ^ false';
+        compile: 'selector_01 ^ 1';
+        compile: 'selector_02 ^ 2';
+        compile: 'selector_03 ^ 3';
+        removeMethod: #selector_02.
+
+    expectedMethodDictionarySources := OrderedCollection new
+        add: 'selector_01 ^ 1';
+        add: 'selector_03 ^ 3';
+        asSortedCollection.
+
+    actualMethodDictionarySources := OrderedCollection new.
+
+    actualMethodDictionarySources := rbClass methodDictionary collect: [ :method |
+        method source    
+    ].
+
+    actualMethodDictionarySources := actualMethodDictionarySources asSortedCollection.
+    
+    self assert: expectedMethodDictionarySources = actualMethodDictionarySources
+
+    "Created: / 02-11-2014 / 11:22:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:29:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_add_and_remove_methods_with_real_class
+    | expectedMethodDictionary actualMethodDictionary expectedMethodDictionaryKeys actualMethodDictionaryKeys realSelector |
+
+    realSelector := #test_method_dictionary_add_and_remove_methods_with_real_class.
+
+    rbClass compileMockMethod: 'isMeta ^ false'.
+    rbClass realClass: self class.
+
+    expectedMethodDictionary := self class methodDictionary 
+        at: #selector_01 putOrAppend: Method new.
+    expectedMethodDictionary := expectedMethodDictionary 
+        at: #selector_03 putOrAppend: Method new.
+    expectedMethodDictionary := expectedMethodDictionary removeKeyAndCompress: realSelector.
+
+    rbClass
+        compile: 'selector_01 ^ 1';
+        compile: 'selector_02 ^ 2';
+        compile: 'selector_03 ^ 3';
+        removeMethod: #selector_02;
+        removeMethod: #test_method_dictionary_add_and_remove_methods_with_real_class.
+
+    actualMethodDictionary := rbClass methodDictionary.
+    expectedMethodDictionaryKeys := expectedMethodDictionary keys asSortedCollection.
+    actualMethodDictionaryKeys := actualMethodDictionary keys asSortedCollection.
+    
+    self assert: expectedMethodDictionaryKeys = actualMethodDictionaryKeys
+
+    "Created: / 30-09-2014 / 21:55:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 02-10-2014 / 21:11:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_dictionary_empty
+    | expectedMethodDictionary actualMethodDictionary |
+
+    expectedMethodDictionary := MethodDictionary new.
+    actualMethodDictionary := rbClass methodDictionary.
+    
+    self assert: (expectedMethodDictionary keys) = (actualMethodDictionary keys)
+
+    "Created: / 30-09-2014 / 19:56:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_do_with_model_class
+    |expectedMethods actualMethods|
+
+    rbClass
+        compileMockMethod:'isMeta ^ false';
+        name:#SomeClass;
+        superclassName:#Object;
+        compile:'selector_01 ^ 1'.
+
+    expectedMethods := OrderedCollection new
+        add:(rbClass compiledMethodAt:#'selector_01');
+        yourself.
+
+    actualMethods := OrderedCollection new.
+
+    rbClass methodsDo:[ :method | 
+        actualMethods add:method 
+    ].
+
+    self assert:expectedMethods = actualMethods
+
+    "Created: / 02-11-2014 / 11:26:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_do_with_model_class_two_methods
+    |expectedMethods actualMethods|
+
+    rbClass
+        compileMockMethod:'isMeta ^ false';
+        name:#SomeClass;
+        superclassName:#Object;
+        compile:'selector_01 ^ 1';
+        compile:'selector_02 ^ 2'.
+
+    expectedMethods := OrderedCollection new
+        add:(rbClass compiledMethodAt:#selector_01);
+        add:(rbClass compiledMethodAt:#selector_02);
+        yourself.
+
+    actualMethods := OrderedCollection new.
+
+    rbClass methodsDo:[ :method | 
+        actualMethods add:method 
+    ].
+
+    self assert:expectedMethods = actualMethods
+
+    "Created: / 02-11-2014 / 11:28:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-11-2014 / 11:13:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_do_with_real_class
+    |actualMethodSelectors|
+
+    rbClass := model classNamed: self class name.
+
+    actualMethodSelectors := OrderedCollection new.
+
+    rbClass methodsDo:[ :method | 
+        actualMethodSelectors add:method selector
+    ].
+
+    self assert:(actualMethodSelectors includes:#test_methods_do_with_real_class).
+    self deny:(actualMethodSelectors includes:#documentation).
+    self assert:(self class class includesSelector:#documentation).
+    self deny:(self class includesSelector:#documentation).
+
+    "Created: / 02-11-2014 / 11:37:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_methods_do_with_real_metaclass
+    |actualMethodSelectors|
+
+    rbClass := model metaclassNamed: self class name.
+
+    actualMethodSelectors := OrderedCollection new.
+
+    rbClass methodsDo:[ :method | 
+        actualMethodSelectors add:method selector
+    ].
+
+    self assert:(actualMethodSelectors includes:#documentation).
+    self deny:(actualMethodSelectors includes:#test_methods_do_with_real_metaclass).
+    self deny:(self class class includesSelector:#test_methods_do_with_real_metaclass).
+    self assert:(self class includesSelector:#test_methods_do_with_real_metaclass).
+
+    "Created: / 02-11-2014 / 11:43:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_set_as_string
+    | expectedName actualName |
+
+    expectedName := #SomeClass01.
+    rbClass name: 'SomeClass01'.
+    actualName := rbClass name.
+
+    self assert: expectedName == actualName
+
+    "Created: / 19-11-2014 / 21:12:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_set_as_symbol
+    | expectedName actualName |
+
+    expectedName := #SomeClass01.
+    rbClass name: #SomeClass01.
+    actualName := rbClass name.
+
+    self assert: expectedName == actualName
+
+    "Created: / 19-11-2014 / 21:15:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_without_prefix_non_prefixed_class
+    | expectedClassName actualClassName |
+
+    rbClass name: #SomeClass.
+    expectedClassName := #SomeClass.
+    actualClassName := rbClass nameWithoutPrefix.  
+
+    self assert: expectedClassName = actualClassName
+
+    "Created: / 05-10-2014 / 00:13:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_name_without_prefix_prefixed_class
+    | expectedClassName actualClassName |
+
+    rbClass name: #'Prefix::SomeClass'.
+    expectedClassName := #SomeClass.
+    actualClassName := rbClass nameWithoutPrefix.  
+
+    self assert: expectedClassName = actualClassName
+
+    "Created: / 05-10-2014 / 00:13:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:17:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class
+    | expectedClass actualClass |
+
+    expectedClass := RBClass new.
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    rbClass := model classNamed: #DummyClass01.  
+    rbClass owningClass: expectedClass.
+
+    actualClass := rbClass owningClass.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:27:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_from_definition_string
+    | expectedClass actualClass |
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    model defineClass: 'Object subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyClass01'.
+
+    expectedClass := model classNamed: #DummyClass01.  
+
+    rbClass := model classNamed: #'DummyClass01::DummyPrivateClass01'.  
+
+    actualClass := rbClass owningClass.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:21:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:16:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_or_yourself_none_owner
+    | expectedClass actualClass |
+
+    rbClass := model classNamed: self class name.  
+    expectedClass := rbClass.
+
+    actualClass := rbClass owningClassOrYourself.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:59:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_or_yourself_owner
+    | expectedClass actualClass |
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    expectedClass := model classNamed: #DummyClass01.
+    rbClass := model classNamed: self class name.  
+    rbClass owningClass: expectedClass.
+
+    actualClass := rbClass owningClassOrYourself.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:56:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_custom
+    | expectedPackage actualPackage |
+
+    expectedPackage := 'some_package'.
+    rbClass package: 'some_package'.
+
+    actualPackage := rbClass package.
+
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 09-10-2014 / 23:40:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_empty
+    | expectedPackage actualPackage |
+
+    expectedPackage := nil.
+    actualPackage := rbClass package.
+
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 09-10-2014 / 23:39:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_from_real_class
+    | expectedPackage actualPackage |
+
+    expectedPackage := self class package.
+
+    self assert: expectedPackage size > 3.
+
+    rbClass realClass: self class.
+
+    actualPackage := rbClass package.
+
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 09-10-2014 / 23:37:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_classes_at_found
+    | expectedClass actualClass |
+
+    model defineClass: 'Object subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:Object'.
+
+    expectedClass := model classNamed: #'Object::DummyPrivateClass01'.
+    self assert: (expectedClass name) = #'Object::DummyPrivateClass01'. 
+
+    rbClass name: #Object.
+    actualClass := rbClass privateClassesAt: #DummyPrivateClass01.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 16-11-2014 / 11:50:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:17:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_classes_at_not_found
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+    actualClass := rbClass privateClassesAt: #None.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 16-11-2014 / 11:41:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_classes_at_not_found_with_name
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+    rbClass name: #DummyClass01.
+    actualClass := rbClass privateClassesAt: #None.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 16-11-2014 / 11:43:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 16-11-2014 / 16:25:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_shared_pool_names
+    
+    self assert: #() = (rbClass realSharedPoolNames)
+
+    "Created: / 16-11-2014 / 16:40:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_source_code_at_existing_method
+    | class expectedSource actualSource |
+
+    class := model createClassImmediate: #DummyClass01.
+    model createMethodImmediate: class source: 'selector_01 ^ 555'. 
+
+    rbClass := model classFor: class.  
+
+    expectedSource := 'selector_01 ^ 555'.
+    actualSource := rbClass sourceCodeAt: #selector_01.  
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 31-01-2015 / 19:14:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_source_code_at_new_method
+    | expectedSource actualSource |
+
+    rbClass name: #DummyClass01; 
+        compileMockMethod: 'isMeta ^ false';
+        compile: 'selector_01 ^ 555'. 
+
+    expectedSource := 'selector_01 ^ 555'.
+    actualSource := rbClass sourceCodeAt: #selector_01.  
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 31-01-2015 / 19:17:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_source_code_at_unknown_method
+    | expectedSource actualSource |
+
+    rbClass name: #DummyClass01; 
+        compileMockMethod: 'isMeta ^ false'.
+
+    expectedSource := nil.
+    actualSource := rbClass sourceCodeAt: #selector_01.  
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 31-01-2015 / 19:20:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_superclass_name
+    | expectedClassName actualClassName |
+
+    rbClass
+        name: #SomeClass;
+        superclassName: (self class name).
+
+    expectedClassName := self class name.
+    actualClassName := rbClass superclass name.
+
+    self assert: expectedClassName = actualClassName
+
+    "Created: / 05-10-2014 / 00:16:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_name_space
+
+    self assert: (rbClass topNameSpace) == (rbClass model)
+
+    "Created: / 16-11-2014 / 16:58:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class
+    | expectedClass actualClass |
+
+    "Class must be defined in the model to have class and metaclass couple"
+    model defineClass: 'Object subclass:#DummyClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    model defineClass: 'Object subclass:#DummyPrivateClass01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        privateIn:DummyClass01'.
+
+    expectedClass := model classNamed: #DummyClass01.  
+
+    rbClass := model classNamed: #'DummyClass01::DummyPrivateClass01'.  
+    rbClass owningClass: expectedClass.
+
+    actualClass := rbClass topOwningClass.
+    
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:12:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:18:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_with_all_superclasses_do_for_one_superclass
+    | expectedClassNames actualClassNames |
+
+    rbClass
+        name: #SomeClass;
+        superclassName: #Object.
+
+    expectedClassNames := OrderedCollection new
+        add: #SomeClass;
+        add: #Object;
+        yourself.
+
+    actualClassNames := OrderedCollection new.
+
+    rbClass withAllSuperclassesDo: [ :class |
+        actualClassNames add: class name.
+    ].
+
+    self assert: expectedClassNames = actualClassNames
+
+    "Created: / 05-10-2014 / 00:22:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBAbstractClassTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBClassTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,345 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBClassTests
+	instanceVariableNames:'rbClass mock model'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBClassTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Test extensions in RBClass.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomRBClassTests methodsFor:'initialization & release'!
+
+setUp
+
+    mock := CustomMock new.
+    model := RBNamespace new.
+    rbClass := mock mockOf: RBClass.
+    rbClass model: model.
+
+    "Created: / 30-09-2014 / 19:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-10-2014 / 00:27:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    mock unmockAll
+
+    "Created: / 30-09-2014 / 19:44:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBClassTests methodsFor:'tests'!
+
+test_compile_for_class
+    | lastChange savedRbClass |
+
+    rbClass
+        name: #SomeClass;
+        superclassName: #Object;
+        instVarNames: #('inst1' 'inst2');
+        classVariableNames: #('Cls1');
+        poolDictionaryNames: (Array with: 'poolDict1');
+        category: 'Some-Test-Category';
+        compile.  
+
+    model changes do: [ :change |
+        lastChange := change
+    ].
+    savedRbClass := model classNamed: #SomeClass.
+
+    self assert: (lastChange isKindOf: AddClassChange).  
+    self assert: (lastChange changeClassName) = #SomeClass.  
+    self assert: (lastChange category) = 'Some-Test-Category'.  
+    self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).  
+    self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).  
+    self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (lastChange superclassName) = #Object.  
+
+    self assert: (savedRbClass isKindOf: RBClass).  
+    self assert: (savedRbClass name) = #SomeClass.  
+    self assert: (savedRbClass category) = 'Some-Test-Category'.  
+    self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).  
+    self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).  
+    self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (savedRbClass superclass name) = #Object.
+
+    "Created: / 05-10-2014 / 00:27:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:24:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_class_with_set_package
+    | lastChange savedRbClass |
+
+    rbClass
+        name: #SomeClass;
+        superclassName: #Object;
+        instVarNames: #('inst1' 'inst2');
+        classVariableNames: #('Cls1');
+        poolDictionaryNames: (Array with: 'poolDict1');
+        category: 'Some-Test-Category';
+        package: 'some_package';
+        compile.  
+
+    model changes do: [ :change |
+        lastChange := change
+    ].
+    savedRbClass := model classNamed: #SomeClass.
+
+    self assert: (lastChange isKindOf: AddClassChange).  
+    self assert: (lastChange changeClassName) = #SomeClass.  
+    self assert: (lastChange category) = 'Some-Test-Category'.  
+    self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).  
+    self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).  
+    self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (lastChange superclassName) = #Object.  
+    self assert: (lastChange package) = 'some_package'.  
+
+    self assert: (savedRbClass isKindOf: RBClass).  
+    self assert: (savedRbClass name) = #SomeClass.  
+    self assert: (savedRbClass category) = 'Some-Test-Category'.  
+    self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).  
+    self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).  
+    self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (savedRbClass superclass name) = #Object.
+    self assert: (savedRbClass package) = 'some_package'.
+
+    "Created: / 09-10-2014 / 23:41:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:25:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_for_real_class_with_set_package
+    | lastChange savedRbClass expectedPackage |
+
+    expectedPackage := self class package deepCopy.
+
+    self assert: expectedPackage notEmpty.
+
+    rbClass := RBClass existingNamed: self class name.
+    rbClass
+        model: model;
+        compile.
+
+    model changes do: [ :change |
+        lastChange := change
+    ].
+    savedRbClass := model classNamed: self class name.
+
+    self assert: (lastChange isKindOf: AddClassChange).
+    self assert: (lastChange package) = expectedPackage.  
+
+    self assert: (savedRbClass isKindOf: RBClass).
+    self assert: (savedRbClass package) = expectedPackage.
+
+    "Created: / 09-10-2014 / 23:54:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:36:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_custom_namespace
+    | lastChange savedRbClass customModel |
+
+    customModel := CustomNamespace new.
+
+    rbClass
+        model: customModel;
+        name: #SomeClass;
+        superclassName: #Object;
+        instVarNames: #('inst1' 'inst2');
+        classVariableNames: #('Cls1');
+        poolDictionaryNames: (Array with: 'poolDict1');
+        category: 'Some-Test-Category';
+        package: #some_package;
+        compile.  
+
+    customModel changes do: [ :change |
+        lastChange := change
+    ].
+
+    savedRbClass := customModel classNamed: #SomeClass.
+
+    self assert: rbClass == savedRbClass.
+
+    self assert: (lastChange isKindOf: AddClassChange).  
+    self assert: (lastChange changeClassName) = #SomeClass.  
+    self assert: (lastChange category) = 'Some-Test-Category'.  
+    self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).  
+    self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).  
+    self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (lastChange superclassName) = #Object.  
+    self assert: (lastChange package) = #some_package.  
+
+    self assert: (savedRbClass isKindOf: RBClass).  
+    self assert: (savedRbClass name) = #SomeClass.  
+    self assert: (savedRbClass category) = 'Some-Test-Category'.  
+    self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).  
+    self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).  
+    self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (savedRbClass superclass name) = #Object.
+    self assert: (savedRbClass package) = #some_package.
+
+    "Created: / 04-11-2014 / 00:17:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:25:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_rb_namespace
+    | lastChange savedRbClass customModel |
+
+    customModel := RBNamespace new.
+
+    rbClass
+        model: customModel;
+        name: #SomeClass;
+        superclassName: #Object;
+        instVarNames: #('inst1' 'inst2');
+        classVariableNames: #('Cls1');
+        poolDictionaryNames: (Array with: 'poolDict1');
+        category: 'Some-Test-Category';
+        package: #some_package;
+        compile.  
+
+    customModel changes do: [ :change |
+        lastChange := change
+    ].
+
+    savedRbClass := customModel classNamed: #SomeClass.
+
+    self assert: (lastChange isKindOf: AddClassChange).  
+    self assert: (lastChange changeClassName) = #SomeClass.  
+    self assert: (lastChange category) = 'Some-Test-Category'.  
+    self assert: (lastChange classVariableNames) = (#('Cls1') asStringCollection).  
+    self assert: (lastChange instanceVariableNames) = (#('inst1' 'inst2') asStringCollection).  
+    self assert: (lastChange poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (lastChange superclassName) = #Object.  
+    self assert: (lastChange package) = #some_package.  
+
+    self assert: (savedRbClass isKindOf: RBClass).  
+    self assert: (savedRbClass name) = #SomeClass.  
+    self assert: (savedRbClass category) = 'Some-Test-Category'.  
+    self assert: (savedRbClass classVariableNames) = (OrderedCollection newFrom: #('Cls1')).  
+    self assert: (savedRbClass instanceVariableNames) = (OrderedCollection newFrom: #('inst1' 'inst2')).  
+    self assert: (savedRbClass poolDictionaryNames) = (OrderedCollection newFrom: #('poolDict1')).  
+    self assert: (savedRbClass superclass name) = #Object.
+    self assert: (savedRbClass package) = #some_package.
+
+    "Created: / 04-11-2014 / 00:17:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:25:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_class_with_set_package
+    | savedRbClass expectedPackage |
+
+    expectedPackage := self class package deepCopy.
+
+    self assert: expectedPackage notEmpty.
+
+    rbClass := RBClass existingNamed: self class name.
+
+    savedRbClass := model classNamed: self class name.
+
+    self assert: (savedRbClass isKindOf: RBClass).
+    self assert: (savedRbClass package) = expectedPackage.
+
+    "Created: / 09-10-2014 / 23:58:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:37:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_the_metaclass_for_new_class
+    | expectedMetaName actualMetaName |
+
+    "Should be 'SomeTestClass class', but if we change it 
+    then some could be broken"
+    expectedMetaName := #SomeTestClass.
+
+    rbClass
+        name: #SomeTestClass;
+        classVariableNames: #();
+        poolDictionaryNames: #();
+        compile. 
+
+    actualMetaName := rbClass theMetaclass name.
+
+    self assert: expectedMetaName = actualMetaName
+
+    "Created: / 08-10-2014 / 12:06:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_the_metaclass_for_real_class
+    | expectedMetaName actualMetaName |
+
+    "Should be 'SomeTestClass class', but if we change it 
+    then some could be broken"
+    expectedMetaName := #Object.
+
+    rbClass 
+        realName: #Object;
+        name: #Object;
+        compile.
+
+    actualMetaName := rbClass theMetaclass name.
+
+    self assert: expectedMetaName = actualMetaName
+
+    "Created: / 08-10-2014 / 12:16:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-10-2014 / 13:42:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBClassTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBLocalSourceCodeFormatter.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,175 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomSourceCodeFormatter subclass:#CustomRBLocalSourceCodeFormatter
+	instanceVariableNames:'localFormatterSettings originalFormatterSettings formatterClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomRBLocalSourceCodeFormatter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Source code formatter based on RBFormatter, but with settings stored in instance variable.
+    Formatting itself temporarily changes global settings then performs formatting and
+    ensures that original settings are restored.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz> 
+"
+! !
+
+!CustomRBLocalSourceCodeFormatter methodsFor:'accessing'!
+
+doesNotUnderstand: aMessage
+    "Store RBFormatter local settings"
+    | selector arguments |
+
+    selector := aMessage selector asSymbol.
+    arguments := aMessage arguments.
+
+    ((formatterClass class canUnderstand: selector) and: [arguments size <= 1]) ifTrue: [
+        (arguments isEmpty) ifTrue: [
+            ^ localFormatterSettings at: selector.
+        ] ifFalse: [
+            | accessor |
+
+            accessor := (selector copyFrom:1 to:(selector size - 1)) asSymbol.
+
+            ^ localFormatterSettings at: accessor put: (arguments first).
+        ]
+    ].
+
+    ^ super doesNotUnderstand: aMessage.
+
+    "Created: / 28-08-2014 / 22:39:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:37:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatterClass
+    ^ formatterClass
+!
+
+formatterClass:something
+    formatterClass := something.
+! !
+
+!CustomRBLocalSourceCodeFormatter methodsFor:'formatting'!
+
+formatParseTree:aParseTree
+    "Return parse tree formatted as source code with custom RBFormatter settings"
+    | source |
+
+    [
+        self setUpFormatterSettings.
+        aParseTree source notNil ifTrue:[
+            "normally aParseTree >> formattedCode should return formatted string,
+            but there is some error with building syntax-valid source code"
+            source := self formatSourceCode: aParseTree source
+        ] ifFalse:[
+            source := aParseTree formattedCode
+        ].
+    ] ensure: [
+        self restoreFormatterSettings.
+    ].
+
+    ^ source
+
+    "Modified: / 29-08-2014 / 00:12:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatSourceCode:aSourceCodeString
+
+    ^ formatterClass format: aSourceCodeString
+
+    "Created: / 28-08-2014 / 23:58:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 31-08-2014 / 10:59:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatter methodsFor:'initialization'!
+
+initialize
+
+    localFormatterSettings := IdentityDictionary new.
+    formatterClass := RBFormatter.
+
+    "Created: / 28-08-2014 / 23:05:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 31-08-2014 / 10:58:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+restoreFormatterSettings
+    "see setUpFormatterSettings "
+
+    originalFormatterSettings keysAndValuesDo: [ :key :value |
+        formatterClass perform: key asMutator with: value.   
+    ].
+
+    "Modified: / 31-08-2014 / 14:59:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+setUpFormatterSettings
+    "Settings for RBFormatter to keep formatting settings independent on system settings.
+    Actually this is not perfect solution because of global scope modifications - imagine
+    parallel execution. "
+
+    originalFormatterSettings := IdentityDictionary new.
+    localFormatterSettings keysAndValuesDo: [ :key :value |
+        originalFormatterSettings at: key put: (formatterClass perform: key).
+        formatterClass perform: key asMutator with: value.   
+    ].
+
+    "Created: / 20-08-2014 / 22:21:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 31-08-2014 / 15:00:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatter class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBLocalSourceCodeFormatterTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,212 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBLocalSourceCodeFormatterTests
+	instanceVariableNames:'spaceAfterReturnToken maxLengthForSingleLineBlocks
+		blockArgumentsOnNewLine formatter'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBLocalSourceCodeFormatterTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests methodsFor:'initialization & release'!
+
+setUp
+    "Original RBFormatter settings"
+
+    spaceAfterReturnToken := RBFormatter spaceAfterReturnToken.
+    maxLengthForSingleLineBlocks := RBFormatter maxLengthForSingleLineBlocks.
+    blockArgumentsOnNewLine := RBFormatter blockArgumentsOnNewLine.
+
+    formatter := CustomRBLocalSourceCodeFormatter new.
+
+    "Modified: / 30-08-2014 / 23:18:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    RBFormatter spaceAfterReturnToken: spaceAfterReturnToken.
+    RBFormatter maxLengthForSingleLineBlocks: maxLengthForSingleLineBlocks.
+    RBFormatter blockArgumentsOnNewLine: blockArgumentsOnNewLine.
+
+    "Modified: / 21-08-2014 / 11:54:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests methodsFor:'private'!
+
+initilizeFormatterSettings: aFormatter
+
+    aFormatter
+        tabIndent: 4;  
+        spaceAroundTemporaries: false;  
+        emptyLineAfterTemporaries: true;  
+        emptyLineAfterMethodComment: true;
+        spaceAfterReturnToken: true;  
+        spaceAfterKeywordSelector: false;  
+        spaceAfterBlockStart: true;  
+        spaceBeforeBlockEnd: true;  
+        cStyleBlocks: true;  
+        blockArgumentsOnNewLine: false;  
+        maxLengthForSingleLineBlocks: 4;
+        periodAfterLastStatementPolicy: #keep.
+
+    "Created: / 30-08-2014 / 23:27:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests methodsFor:'tests'!
+
+test_format_parse_tree_source_is_nil
+    | expectedSource actualSource parseTree source |
+
+    source := 'selector ^ 777'.
+    parseTree := RBParser parseMethod: source.
+    parseTree source: nil.
+
+    formatter tabIndent: 4.
+    formatter spaceAfterReturnToken: true.
+
+    actualSource := formatter formatParseTree: parseTree.    
+    expectedSource := 'selector
+    ^ 777'.
+
+    self assert: actualSource = expectedSource.
+
+    "Created: / 31-08-2014 / 14:59:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_format_parse_tree_source_not_nil
+    | expectedSource actualSource parseTree source |
+
+    source := 'selector ^ 777'.
+    parseTree := RBParser parseMethod: source.
+    parseTree source: source.
+
+    formatter tabIndent: 4.
+    formatter spaceAfterReturnToken: true.
+
+    actualSource := formatter formatParseTree: parseTree.    
+    expectedSource := 'selector
+    ^ 777'.
+
+    self assert: actualSource = expectedSource.
+
+    "Created: / 31-08-2014 / 14:58:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_format_source_code
+    "Assert that some formatting is made."
+
+    | sourceCodeString actualSource |
+
+    sourceCodeString := 'selector ^ 563'.
+
+    actualSource := formatter formatSourceCode: sourceCodeString.    
+    
+    self deny: sourceCodeString = actualSource.
+
+    "Created: / 30-08-2014 / 23:24:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 09-09-2014 / 21:47:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_formatter_setting_set_and_get
+
+    | expectedTabIndent actualTabIndent |
+
+    self deny: (formatter class canUnderstand: #tabIndent:).  
+    self deny: (formatter class canUnderstand: #tabIndent).  
+
+    formatter tabIndent: 10.    
+
+    expectedTabIndent := 10.
+    actualTabIndent := formatter tabIndent.
+
+    self assert: expectedTabIndent = actualTabIndent.
+
+    "Created: / 31-08-2014 / 14:42:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_formatter_setting_unknown
+
+    self deny: (formatter class canUnderstand: #someUnknownSetting:).  
+
+    self should: [
+        formatter someUnknownSetting: 10
+    ] raise: MessageNotUnderstood
+
+    "Created: / 31-08-2014 / 14:44:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_formatter_settings_modified_and_then_restored
+
+    formatter
+        spaceAfterReturnToken: (spaceAfterReturnToken isNil ifTrue: [ true ] ifFalse: [ spaceAfterReturnToken not ]);  
+        maxLengthForSingleLineBlocks: (spaceAfterReturnToken isNil ifTrue: [ 21 ] ifFalse: [ maxLengthForSingleLineBlocks + 10 ]);
+        blockArgumentsOnNewLine: (blockArgumentsOnNewLine isNil ifTrue: [ true ] ifFalse: [ blockArgumentsOnNewLine not ]).
+
+    formatter setUpFormatterSettings.
+
+    self assert: (RBFormatter spaceAfterReturnToken) == (spaceAfterReturnToken isNil ifTrue: [ true ] ifFalse: [ spaceAfterReturnToken not ]).
+    self assert: (RBFormatter maxLengthForSingleLineBlocks) == (spaceAfterReturnToken isNil ifTrue: [ 21 ] ifFalse: [ maxLengthForSingleLineBlocks + 10 ]).
+    self assert: (RBFormatter blockArgumentsOnNewLine) == (blockArgumentsOnNewLine isNil ifTrue: [ true ] ifFalse: [ blockArgumentsOnNewLine not ]).
+
+    formatter restoreFormatterSettings.
+
+    self assert: (RBFormatter spaceAfterReturnToken) == spaceAfterReturnToken.
+    self assert: (RBFormatter maxLengthForSingleLineBlocks) == maxLengthForSingleLineBlocks.
+    self assert: (RBFormatter blockArgumentsOnNewLine) == blockArgumentsOnNewLine.
+
+    "Created: / 21-08-2014 / 11:44:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-08-2014 / 23:40:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBLocalSourceCodeFormatterTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBMetaclassTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,314 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBMetaclassTests
+	instanceVariableNames:'rbClass mock model'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+CustomRBMetaclassTests subclass:#MockPrivateClass01
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRBMetaclassTests
+!
+
+CustomRBMetaclassTests::MockPrivateClass01 subclass:#MockPrivateClass03
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRBMetaclassTests::MockPrivateClass01
+!
+
+Object subclass:#MockPrivateClass02
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRBMetaclassTests
+!
+
+!CustomRBMetaclassTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Test extensions in RBMetaclass.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz> 
+
+"
+! !
+
+!CustomRBMetaclassTests methodsFor:'initialization & release'!
+
+setUp
+
+    mock := CustomMock new.
+    model := RBNamespace new.
+    rbClass := mock mockOf: RBMetaclass.
+    rbClass model: model.
+
+    "Created: / 29-11-2014 / 02:28:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    mock unmockAll
+
+    "Created: / 29-11-2014 / 02:28:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMetaclassTests methodsFor:'tests'!
+
+test_owning_class_empty
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:37:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_model_class
+    | expectedClass actualClass |
+
+    expectedClass := RBClass new.
+    rbClass owningClass: expectedClass.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:43:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_model_metaclass
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: self class name.
+    rbClass owningClass: expectedClass theMetaclass.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:39:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_real_class
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: self class name.
+    rbClass owningClass: self class.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:42:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_set_real_metaclass
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: self class name.
+    rbClass owningClass: self class theMetaclass.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:37:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+    rbClass realClass: SmallSense::CustomRBMetaclassTests::MockPrivateClass01.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 02:31:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-11-2014 / 12:19:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:28:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class_with_different_superclass
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+    rbClass realClass: CustomRBMetaclassTests::MockPrivateClass02.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:20:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:28:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_owning_class_with_real_class_without_owner
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+
+    rbClass realClass: CustomRBMetaclassTests.
+    actualClass := rbClass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 12:21:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_01
+    | expectedClass actualClass |
+
+    "Cannot use self class, because TestRunner eats also private classes
+    and when running in private class the class is different"
+    expectedClass := CustomRBMetaclassTests.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:34:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 30-11-2014 / 17:18:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_02
+    | expectedClass actualClass |
+
+    "Cannot use self class, because TestRunner eats also private classes
+    and when running in private class the class is different"
+    expectedClass := CustomRBMetaclassTests.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 class owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:35:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 30-11-2014 / 17:18:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_03
+    | expectedClass actualClass |
+
+    "Cannot use self class, because TestRunner eats also private classes
+    and when running in private class the class is different"
+    expectedClass := CustomRBMetaclassTests.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 theMetaclass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:35:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 30-11-2014 / 17:18:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_private_class_04
+    | expectedClass actualClass |
+
+    "Cannot use self class, because TestRunner eats also private classes
+    and when running in private class the class is different"
+    expectedClass := CustomRBMetaclassTests.
+    actualClass := CustomRBMetaclassTests::MockPrivateClass01 theNonMetaclass owningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:35:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 30-11-2014 / 17:18:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class_empty
+    | expectedClass actualClass |
+
+    expectedClass := nil.
+    actualClass := rbClass topOwningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 13:53:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_top_owning_class_with_real_class
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+    rbClass realClass: CustomRBMetaclassTests::MockPrivateClass01.
+    actualClass := rbClass topOwningClass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:04:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:28:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_top_owning_class_with_real_class_two_level
+    | expectedClass actualClass |
+
+    expectedClass := model classNamed: #'SmallSense::CustomRBMetaclassTests'.
+
+    rbClass realClass: CustomRBMetaclassTests::MockPrivateClass01 myMockPrivateClass03.
+    actualClass := rbClass topOwningClass.
+
+    self assert: (rbClass realClass name) = #'SmallSense::CustomRBMetaclassTests::MockPrivateClass01::MockPrivateClass03'.
+    self assert: expectedClass = actualClass
+
+    "Created: / 29-11-2014 / 14:05:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 13:13:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:29:24 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomRBMetaclassTests::MockPrivateClass01 class methodsFor:'accessing'!
+
+myMockPrivateClass03
+    "Returns my private class (for testing purposes)"
+
+    ^ MockPrivateClass03
+
+    "Created: / 29-11-2014 / 14:08:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRBMethodTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,731 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRBMethodTests
+	instanceVariableNames:'rbMethod mock model'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRBMethodTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomRBMethodTests methodsFor:'initialization & release'!
+
+setUp
+
+    mock := CustomMock new.
+    rbMethod := mock mockOf: RBMethod.
+    model := RBNamespace new.
+    rbMethod model: model.
+
+    "Created: / 30-09-2014 / 19:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 06-10-2014 / 07:38:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+tearDown
+
+    mock unmockAll
+
+    "Created: / 30-09-2014 / 19:44:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMethodTests methodsFor:'tests'!
+
+test_category_custom_set
+    | expectedCategory actualCategory |
+
+    expectedCategory := 'test category'.
+
+    rbMethod category: expectedCategory. 
+    actualCategory := rbMethod category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 06-10-2014 / 08:11:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_empty
+    | expectedCategory actualCategory |
+
+    expectedCategory := 'as yet unclassified'.
+
+    "actually we need to set model class with real class
+    and selector or source to retrieve 'as yet unclassified' category/protocol"
+    rbMethod
+        modelClass: (model classNamed: #Object);
+        selector: #someSelector.
+    actualCategory := rbMethod category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 06-10-2014 / 08:12:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_empty_with_none_class
+    | expectedCategory actualCategory |
+
+    expectedCategory := 'as yet unclassified'.
+
+    actualCategory := rbMethod category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 08-10-2014 / 18:40:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_from_compiled_method
+    | expectedCategory actualCategory |
+
+    expectedCategory := 'tests'.
+
+    rbMethod method: (self class compiledMethodAt: #test_category_from_compiled_method).
+    actualCategory := rbMethod category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 06-10-2014 / 08:20:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_from_real_class
+    | expectedCategory actualCategory |
+
+    expectedCategory := 'tests'.
+
+    rbMethod
+        class: self class;
+        selector: #test_category_from_real_class.
+
+    actualCategory := rbMethod category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 06-10-2014 / 08:21:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_for_model_class
+    | expectedModelClass actualModelClass |
+
+    expectedModelClass := RBClass new.
+
+    rbMethod class: expectedModelClass. 
+    actualModelClass := rbMethod modelClass.
+
+    self assert: expectedModelClass = actualModelClass
+
+    "Created: / 06-10-2014 / 07:36:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_for_real_class
+    | expectedModelClass actualModelClass |
+
+    expectedModelClass := model classNamed: #Object.
+
+    rbMethod class: Object. 
+    actualModelClass := rbMethod modelClass.
+
+    self assert: expectedModelClass = actualModelClass
+
+    "Created: / 06-10-2014 / 07:36:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_class_for_real_metaclass
+    | expectedModelClass actualModelClass |
+
+    expectedModelClass := model metaclassNamed: #Object.
+
+    rbMethod class: Object class. 
+    actualModelClass := rbMethod modelClass.
+
+    self assert: expectedModelClass = actualModelClass
+
+    "Created: / 06-10-2014 / 07:42:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_code_generator
+    | actualMethod generator class source expectedSource actualSource |
+
+    generator := CustomSourceCodeGenerator new
+        formatter: CustomNoneSourceCodeFormatter new;
+        yourself.
+
+    class := RBClass new
+        name: #SomeTestClass;
+        model: model;
+        superclassName: #Object;
+        yourself.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+    self assert: actualMethod isNil. 
+
+    source := 'selector_01
+    "Comment"
+
+    `variable := 500.
+    ^ `variable'.
+
+    expectedSource := 'selector_01
+    "Comment"
+
+    variableName := 500.
+    ^ variableName'.
+
+    rbMethod
+        class: class;
+        sourceCodeGenerator: generator;
+        source: source;
+        replace: '`variable' with: 'variableName';
+        protocol: 'test protocol';
+        compile.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+    actualSource := actualMethod source.
+
+    self assert: actualSource = expectedSource.
+    self assert: (actualMethod protocol) = (rbMethod protocol)
+
+    "Created: / 06-10-2014 / 22:45:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 15:14:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_with_custom_package
+    | actualMethod class change |
+
+    class := RBClass new
+        name: #SomeTestClass;
+        model: model;
+        superclassName: #Object;
+        yourself.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+    self assert: actualMethod isNil. 
+
+    change := rbMethod
+        class: class;
+        source: 'selector_01 ^ 12';
+        protocol: 'test protocol';
+        package: 'my_package';
+        compile.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+
+    self assert: (actualMethod source) = (rbMethod source).
+    self assert: (actualMethod protocol) = (rbMethod protocol).
+    self assert: (actualMethod package) = (rbMethod package).
+
+    self assert: (change source) = (rbMethod source).
+    self assert: (change protocol) = (rbMethod protocol).
+    self assert: (change package) = (rbMethod package).
+
+    "Created: / 10-10-2014 / 11:25:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_without_code_generator
+    | actualMethod class |
+
+    class := RBClass new
+        name: #SomeTestClass;
+        model: model;
+        superclassName: #Object;
+        yourself.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+    self assert: actualMethod isNil. 
+
+    rbMethod
+        class: class;
+        source: 'selector_01 ^ 12';
+        protocol: 'test protocol';
+        compile.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+
+    self assert: (actualMethod source) = (rbMethod source).
+    self assert: (actualMethod protocol) = (rbMethod protocol)
+
+    "Created: / 06-10-2014 / 21:11:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 06-10-2014 / 22:33:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compile_without_custom_package
+    | actualMethod class change |
+
+    class := RBClass new
+        name: #SomeTestClass;
+        model: model;
+        superclassName: #Object;
+        yourself.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+    self assert: actualMethod isNil. 
+
+    change := rbMethod
+        class: class;
+        source: 'selector_01 ^ 12';
+        protocol: 'test protocol';
+        compile.
+
+    actualMethod := class compiledMethodAt: #selector_01.
+
+    self assert: (actualMethod source) = (rbMethod source).
+    self assert: (actualMethod protocol) = (rbMethod protocol).
+    self assert: (actualMethod package) = (rbMethod package).
+
+    self assert: (change source) = (rbMethod source).
+    self assert: (change protocol) = (rbMethod protocol).
+    self assert: (change package) = (rbMethod package).
+
+    "Created: / 10-10-2014 / 11:51:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_empty
+    | expectedMethod actualMethod |
+
+    expectedMethod := nil.
+    actualMethod := rbMethod method.
+
+    self assert: expectedMethod = actualMethod
+
+    "Created: / 08-10-2014 / 19:27:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_for_real_method
+    | expectedMethod actualMethod |
+
+    expectedMethod := self class compiledMethodAt: #test_compiled_method_for_real_method.
+
+    rbMethod := RBMethod 
+        for: RBClass new 
+        fromMethod: expectedMethod 
+        andSelector: #test_compiled_method_for_real_method.
+
+    actualMethod := rbMethod method.
+
+    self assert: expectedMethod = actualMethod
+
+    "Created: / 08-10-2014 / 19:30:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_for_real_method_empty
+    | expectedMethod actualMethod |
+
+    expectedMethod := self class compiledMethodAt: #test_compiled_method_for_real_method.
+
+    rbMethod 
+        modelClass: (RBClass existingNamed: self className asSymbol); 
+        selector: #test_compiled_method_for_real_method.
+
+    actualMethod := rbMethod method.
+
+    self assert: expectedMethod = actualMethod
+
+    "Created: / 08-10-2014 / 19:32:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_compiled_method_when_selector_empty
+    | expectedMethod actualMethod |
+
+    expectedMethod := nil.
+
+    rbMethod 
+        modelClass: (RBClass existingNamed: self className asSymbol);
+        source: 'selector_01 ^ 1'.
+
+    actualMethod := rbMethod method.
+
+    self assert: expectedMethod = actualMethod
+
+    "Created: / 08-10-2014 / 19:36:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_mclass
+    | expectedClass actualClass |
+
+    expectedClass := RBClass new. 
+    rbMethod modelClass: expectedClass.
+
+    actualClass := rbMethod mclass.
+
+    self assert: expectedClass = actualClass
+
+    "Created: / 25-11-2014 / 22:27:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 27-11-2014 / 23:18:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_arg_names_none_arg
+    | expectedArguments actualArguments |
+
+    expectedArguments := nil.
+
+    rbMethod source: 'selector ^ 5'. 
+    actualArguments := rbMethod methodArgNames.
+
+    self assert: expectedArguments = actualArguments
+
+    "Created: / 07-10-2014 / 21:39:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_arg_names_one_arg
+    | expectedArguments actualArguments |
+
+    expectedArguments := #('arg_01').
+
+    rbMethod source: 'selector: arg_01 ^ 5'. 
+    actualArguments := rbMethod methodArgNames.
+
+    self assert: expectedArguments = actualArguments
+
+    "Created: / 07-10-2014 / 21:39:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_arg_names_two_args
+    | expectedArguments actualArguments |
+
+    expectedArguments := #('arg_01' 'arg_02').
+
+    rbMethod source: 'selector: arg_01 param: arg_02 ^ 5'. 
+    actualArguments := rbMethod methodArgNames.
+
+    self assert: expectedArguments = actualArguments
+
+    "Created: / 07-10-2014 / 21:57:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_definition_template_none_arg
+    | expectedMethodDefinition actualMethodDefinition |
+
+    expectedMethodDefinition := 'selector'.
+
+    rbMethod source: 'selector ^ 5'. 
+    actualMethodDefinition := rbMethod methodDefinitionTemplate.
+
+    self assert: expectedMethodDefinition = actualMethodDefinition
+
+    "Created: / 07-10-2014 / 22:32:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_method_definition_template_two_args
+    | expectedMethodDefinition actualMethodDefinition |
+
+    expectedMethodDefinition := 'selector:arg_01 param:arg_02'.
+
+    rbMethod source: 'selector: arg_01 param: arg_02 ^ 5'. 
+    actualMethodDefinition := rbMethod methodDefinitionTemplate.
+
+    self assert: expectedMethodDefinition = actualMethodDefinition
+
+    "Created: / 07-10-2014 / 22:24:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_code_generator_with_replacements
+    | expectedSource actualSource |
+
+    expectedSource := 'selector_01 ^ 1'.
+    rbMethod
+        source: 'selector_01 ^ `#literal';
+        sourceCodeGenerator: ( CustomSourceCodeGenerator new
+            formatter: CustomNoneSourceCodeFormatter new;
+            yourself);
+        replace: '`#literal' with: '1'.
+
+    actualSource := rbMethod newSource.
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 10-10-2014 / 15:12:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_none_code_generator
+    | expectedSource actualSource |
+
+    expectedSource := 'selector_01 ^ 1'.
+    rbMethod source: 'selector_01 ^ 1'.
+
+    actualSource := rbMethod newSource.
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 10-10-2014 / 14:43:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_some_code_generator
+    | expectedSource actualSource |
+
+    expectedSource := 'selector_01 ^ 1'.
+    rbMethod
+        source: 'selector_01 ^ 1';
+        sourceCodeGenerator: ( CustomSourceCodeGenerator new
+            formatter: CustomNoneSourceCodeFormatter new;
+            yourself).
+
+    actualSource := rbMethod newSource.
+
+    self assert: expectedSource = actualSource
+
+    "Created: / 10-10-2014 / 15:10:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_custom
+    | expectedPackage actualPackage |
+
+    expectedPackage := 'some_package'.
+
+    rbMethod package: 'some_package'.    
+    actualPackage := rbMethod package. 
+
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 10-10-2014 / 11:20:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_empty
+    | expectedPackage actualPackage |
+
+    expectedPackage := PackageId noProjectID.
+    actualPackage := rbMethod package. 
+
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 10-10-2014 / 11:16:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_package_from_real_method
+    | expectedPackage actualPackage |
+
+    expectedPackage := self class package.
+
+    self assert: expectedPackage size > 3.
+
+    rbMethod method: (self class compiledMethodAt: #test_package_from_real_method).    
+    actualPackage := rbMethod package. 
+
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 10-10-2014 / 11:16:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_programming_language_default
+    | expectedLanguage actualLanguage |
+
+    expectedLanguage := SmalltalkLanguage instance.
+    actualLanguage := rbMethod programmingLanguage.
+
+    self assert: expectedLanguage = actualLanguage
+
+    "Created: / 26-12-2014 / 12:17:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_programming_language_from_real_class
+    | expectedLanguage actualLanguage |
+
+    expectedLanguage := JavaLanguage instance.
+    rbMethod modelClass: (RBClass new realClass: JavaClass new; yourself).
+    actualLanguage := rbMethod programmingLanguage.
+
+    self assert: expectedLanguage = actualLanguage
+
+    "Created: / 26-12-2014 / 12:59:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_programming_language_from_real_method
+    | expectedLanguage actualLanguage |
+
+    expectedLanguage := JavaLanguage instance.
+    rbMethod method: (JavaMethod new mclass: JavaClass new; yourself).
+    actualLanguage := rbMethod programmingLanguage.
+
+    self assert: expectedLanguage = actualLanguage
+
+    "Created: / 26-12-2014 / 12:23:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_method_arg_names_none_arg
+    "to check what Method >> methodArgNames returns"
+
+    | expectedArguments actualArguments class method |
+
+    class := mock mockClassOf: Object.  
+    class new compileMockMethod: 'selector ^ 5'.
+    method := class compiledMethodAt: #selector.  
+
+    expectedArguments := nil.
+    actualArguments := method methodArgNames.
+
+    self assert: expectedArguments = actualArguments
+
+    "Created: / 07-10-2014 / 21:41:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_method_arg_names_one_arg
+    "to check what Method >> methodArgNames returns"
+
+    | expectedArguments actualArguments class method |
+
+    class := mock mockClassOf: Object.  
+    class new compileMockMethod: 'selector: arg_01 ^ 5'.
+    method := class compiledMethodAt: #selector:.  
+
+    expectedArguments := #('arg_01').
+    actualArguments := method methodArgNames.
+
+    self assert: expectedArguments = actualArguments
+
+    "Created: / 07-10-2014 / 21:53:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_real_method_arg_names_two_args
+    "to check what Method >> methodArgNames returns"
+
+    | expectedArguments actualArguments class method |
+
+    class := mock mockClassOf: Object.  
+    class new compileMockMethod: 'selector: arg_01 param: arg_02 ^ 5'.
+    method := class compiledMethodAt: #selector:param:.  
+
+    expectedArguments := #('arg_01' 'arg_02').
+    actualArguments := method methodArgNames.
+
+    self assert: expectedArguments = actualArguments
+
+    "Created: / 07-10-2014 / 21:55:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_empty
+    | expectedSelector actualSelector |
+
+    expectedSelector := nil.
+    actualSelector := rbMethod selector.
+
+    self assert: expectedSelector = actualSelector
+
+    "Created: / 26-12-2014 / 13:33:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_empty_for_empty_source
+    | expectedSelector actualSelector |
+
+    expectedSelector := nil.
+    rbMethod source: ''.
+    actualSelector := rbMethod selector.
+
+    self assert: expectedSelector = actualSelector
+
+    "Created: / 26-12-2014 / 13:33:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_from_source
+    | expectedSelector actualSelector |
+
+    expectedSelector := #selector_01.
+    rbMethod source: 'selector_01 ^ 1'.
+    actualSelector := rbMethod selector.
+
+    self assert: expectedSelector = actualSelector
+
+    "Created: / 26-12-2014 / 13:37:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selector_set
+    | expectedSelector actualSelector |
+
+    expectedSelector := #selector_01.
+    rbMethod selector: expectedSelector.
+    actualSelector := rbMethod selector.
+
+    self assert: expectedSelector = actualSelector
+
+    "Created: / 26-12-2014 / 13:39:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_sends_literal_or_sends_another_literal_first
+
+    rbMethod source: 'selector ^ self subclassResponsibility'.  
+
+    self assert: (rbMethod sends:#subclassResponsibility or:#subclassResponsibility:)
+
+    "Created: / 03-10-2014 / 20:14:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_sends_literal_or_sends_another_literal_second
+
+    rbMethod source: 'selector
+    "comment"
+
+    ^ self subclassResponsibility: #arg.'.  
+
+    self assert: (rbMethod sends:#subclassResponsibility or:#subclassResponsibility:)
+
+    "Created: / 04-10-2014 / 00:03:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_sends_literal_or_sends_another_with_real_method
+    | someObject |
+
+    someObject := mock mockOf: Object.
+    someObject compileMockMethod: 'selector_01
+    "comment"
+
+    ^ self subclassResponsibility: #arg.'.
+
+    self assert: ((someObject class compiledMethodAt: #selector_01) isKindOf: CompiledCode).
+
+    rbMethod := RBMethod 
+        for: (RBClass existingNamed: someObject className asSymbol)   
+        fromMethod: (someObject class compiledMethodAt: #selector_01) 
+        andSelector: #selector_01. 
+
+
+    self assert: (rbMethod sends:#subclassResponsibility or:#subclassResponsibility:)
+
+    "Created: / 04-10-2014 / 00:05:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRBMethodTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoring.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,79 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoring subclass:#CustomRefactoring
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomRefactoring class methodsFor:'testing'!
+
+isAbstract
+    ^ self == CustomRefactoring
+
+    "Created: / 26-01-2014 / 21:39:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isCustomRefactoring
+    ^ true
+! !
+
+!CustomRefactoring methodsFor:'testing'!
+
+isCustomRefactoring
+    ^ true
+! !
+
+!CustomRefactoring class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoringClassGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,105 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomNewClassGenerator subclass:#CustomRefactoringClassGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomRefactoringClassGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomRefactoringClassGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+    ^ 'Create new class which should perform some refactoring'
+
+    "Modified: / 09-11-2014 / 00:51:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+
+    ^ #(Generators)
+
+    "Created: / 08-11-2014 / 17:19:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+
+    ^ 'New Refactoring'
+
+    "Modified: / 08-11-2014 / 17:18:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoringClassGenerator methodsFor:'accessing - ui'!
+
+defaultClassName
+
+    ^ 'CustomXXXRefactoring'
+
+    "Created: / 08-11-2014 / 17:15:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newClassNameLabel
+
+    ^ 'Enter class name for new refactoring'
+
+    "Created: / 08-11-2014 / 17:16:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoringClassGenerator methodsFor:'executing - private'!
+
+buildForClass: aClass
+
+    aClass
+        superclassName: CustomRefactoring name;
+        category: CustomRefactoring category
+
+    "Created: / 08-11-2014 / 17:15:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:05:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoringClassGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,83 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomRefactoringClassGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomRefactoringClassGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomRefactoringClassGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomRefactoringClassGenerator new
+! !
+
+!CustomRefactoringClassGeneratorTests methodsFor:'tests'!
+
+test_refactoring_subclass_created
+    | expectedSource class |
+
+    expectedSource := 'buildInContext:aCustomContext
+    self shouldImplement'.
+
+    generatorOrRefactoring
+        newClassName: #DummyClass01;  
+        executeInContext: context.  
+
+    self assertClassExists: #DummyClass01.  
+
+    class := Smalltalk at: #DummyClass01.
+
+    self assertMethodSource:expectedSource atSelector:#buildInContext: forClass: class.  
+    self assert: (class superclass name) = #SmallSense::CustomRefactoring.
+
+    "Created: / 09-11-2014 / 01:04:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:03:02 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoryBuilder.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,704 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomRefactoryBuilder
+	instanceVariableNames:'changeManager formatter model rewritterClass searcherClass
+		parserClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+CustomRefactoryBuilder subclass:#ClassCategorySearcher
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#ClassSearcher
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#CodeSelectionSearcher
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#MethodSearcher
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#PackageSearcher
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRefactoryBuilder
+!
+
+CustomRefactoryBuilder subclass:#ProtocolSearcher
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomRefactoryBuilder
+!
+
+!CustomRefactoryBuilder class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Encapsulates performing refactoring changes on the source code within single object. 
+    Single refactorings are stored as change objects which represens changes in the source code.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz> 
+
+"
+! !
+
+!CustomRefactoryBuilder class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!CustomRefactoryBuilder methodsFor:'accessing'!
+
+changeManager
+    ^ changeManager
+!
+
+changeManager:something
+    changeManager := something.
+!
+
+formatter
+    ^ formatter
+!
+
+formatter: aFormatter
+    formatter := aFormatter.
+
+    "Modified (format): / 31-08-2014 / 17:12:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+model
+    ^ model
+!
+
+model:something
+    model := something.
+!
+
+parser
+    "Returns prepared source code parser"
+
+    ^ parserClass
+
+    "Created: / 24-08-2014 / 23:36:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 22:02:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parserClass
+    "Returns a class used to parse the source code (i.e. RBParser)"
+
+    ^ parserClass
+
+    "Modified (comment): / 10-12-2014 / 22:01:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parserClass: aClass
+    "see parserClass"
+
+    parserClass := aClass
+
+    "Modified (comment): / 10-12-2014 / 21:59:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+rewritterClass
+    "Returns a class used for rewriting the source code.
+    For example CustomParseTreeRewriter."
+
+    ^ rewritterClass
+
+    "Modified (comment): / 10-12-2014 / 21:16:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+rewritterClass: aClass
+    "see rewritterClass"
+
+    rewritterClass := aClass.
+
+    "Modified (comment): / 10-12-2014 / 21:16:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+searcher
+    "Returns prepared source code searcher"
+
+    ^ searcherClass new
+
+    "Created: / 16-08-2014 / 22:13:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 22:03:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+searcherClass
+    "Returns a class used to search on the source code (i.e. ParseTreeSearcher)"
+
+    ^ searcherClass
+
+    "Modified (comment): / 10-12-2014 / 22:00:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+searcherClass:something
+    searcherClass := something.
+! !
+
+!CustomRefactoryBuilder methodsFor:'compiling'!
+
+execute
+    "Performs code changes ( add method, add class, rename class... )
+    so they take in effect ( method is added, class is renamed, ... )
+    with respect to current change manager implementatin - see CustomChangeManager subclasses."
+
+    model execute
+
+    "Created: / 15-08-2014 / 00:45:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 17:42:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+undoChanges
+    "redo all changes made by execute method"
+
+    model undoChanges
+
+    "Created: / 19-10-2014 / 14:57:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 17:42:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'initialization'!
+
+initialize
+
+    super initialize.
+    model := CustomNamespace new.
+    rewritterClass := CustomParseTreeRewriter.
+    searcherClass := ParseTreeSearcher.
+    parserClass := RBParser.
+
+    "Created: / 15-08-2014 / 00:42:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 22:04:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'parsing'!
+
+parse: aSourceCode codeSelection: aCodeSelection
+    "Retuns a parse tree from given source code string
+    depending on what is selected within a method."
+
+    aCodeSelection isWholeMethodSelected ifTrue: [ 
+        ^ self parseMethod: aSourceCode  
+    ].
+
+    ^ self parseExpression: aSourceCode
+
+    "Created: / 10-12-2014 / 21:40:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parseExpression: aSourceCode
+    "Helper for retrieving parse tree from source code string.
+    Assume thats expression and if parsing fails then try method parsing."
+
+    ^ self parser parseExpression: aSourceCode onError: [ :string :pos |
+        self parser parseRewriteMethod: aSourceCode onError: [ :string :pos |
+            self error: 'Could not parse ', string, ' at pos ', pos asString
+        ]
+    ]
+
+    "Created: / 25-08-2014 / 22:34:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 21:55:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+parseMethod: aSourceCode
+    "Helper for retrieving parse tree from source code string.
+    Assume thats method and if parsing fails then try expression parsing."
+
+    ^ self parser parseRewriteMethod: aSourceCode onError: [ :string :pos |
+        self parser parseExpression: aSourceCode onError: [ :string :pos |
+            self error: 'Could not parse ', string, ' at pos ', pos asString
+        ]
+    ]
+
+    "Created: / 25-08-2014 / 22:35:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 21:55:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'refactory - changes'!
+
+changeCategoryOf: aClass to: aCategory
+    "Changes class category to the given one in given class"
+    | change |
+
+    (self model classFor: aClass) category: aCategory.
+
+    change := (self initializeChange: RefactoryClassCategoryChange)
+        changeClass: aClass;
+        category: aCategory;
+        yourself.
+
+    model changes addChange: change
+
+    "Created: / 08-11-2014 / 13:40:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 17:35:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+executeReplace: searchPattern with: rewritePattern inCodeSelection: aCodeSelection
+    "Performs replacement on some code selection within method source code.
+    Firstly the search and relace is limited just to some selection 
+    (i.e. some expression, but whole method can be selected)
+    and then is this new code inserted in the method source code."
+    | parseTree foundMatch rewriter selectedCode |
+
+    selectedCode := aCodeSelection selectedSourceCode.
+    parseTree := self parse: selectedCode codeSelection: aCodeSelection.
+
+    rewriter := rewritterClass new
+        oldSource: aCodeSelection selectedSourceCode;  
+        replace: searchPattern with: rewritePattern;
+        yourself.
+
+    foundMatch := rewriter executeTree: parseTree.
+
+    foundMatch ifTrue: [
+        | change newSource newParseTree |
+
+        newSource := rewriter tree newSource.
+        newParseTree := self parse: newSource codeSelection: aCodeSelection.
+        newSource := formatter formatParseTree: newParseTree.
+
+        aCodeSelection selectedInterval notNil ifTrue: [
+            rewriter := rewritterClass new.
+            foundMatch := rewriter
+                replace: selectedCode with: newSource when: [ :aNode | 
+                    aNode intersectsInterval: aCodeSelection selectedInterval 
+                ];
+                executeTree: (self parseMethod: aCodeSelection currentSourceCode).
+
+            newSource := rewriter newSource.
+        ].
+
+        (foundMatch and: [ newSource notNil ]) ifTrue: [   
+            change := model
+                compile: newSource
+                in: aCodeSelection selectedMethod mclass 
+                classified: aCodeSelection selectedMethod category.
+
+            change package: aCodeSelection selectedMethod package
+        ]
+    ].
+
+    "Created: / 24-08-2014 / 10:24:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-02-2015 / 21:57:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeChange: aChangeClass
+    "Returns new initialized instance of a code change like AddClassChange"
+
+    ^ aChangeClass new
+        model: self model;
+        yourself
+
+    "Created: / 08-11-2014 / 16:10:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replace: searchPattern with: rewritePattern inContext: aCustomContext
+    "Searches for given pattern in methods source code or selected code fragments
+    and if source code matches then executes replacement"
+
+    self 
+        search: searchPattern 
+        inContext: aCustomContext 
+        withResultDo: [ :sourceSelection |
+            self executeReplace: searchPattern with: rewritePattern inCodeSelection: sourceSelection 
+        ]
+
+    "Created: / 16-08-2014 / 19:15:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 22:14:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'searching - instance creation'!
+
+classCategorySearcher
+
+    ^ self initializeSearcher: ClassCategorySearcher
+
+    "Created: / 04-11-2014 / 18:47:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+classSearcher
+
+    ^ self initializeSearcher: ClassSearcher
+
+    "Created: / 04-11-2014 / 21:43:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+codeSelectionSearcher
+
+    ^ self initializeSearcher: CodeSelectionSearcher
+
+    "Created: / 04-11-2014 / 22:36:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+initializeSearcher: searcherClass
+    "Returns new searcher with prepared instance variables."
+
+    ^ searcherClass new
+        model: model;
+        yourself
+
+    "Created: / 03-11-2014 / 09:45:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodSearcher
+
+    ^ self initializeSearcher: MethodSearcher
+
+    "Created: / 04-11-2014 / 22:32:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+packageSearcher
+
+    ^ self initializeSearcher: PackageSearcher
+
+    "Created: / 01-11-2014 / 19:52:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 03-11-2014 / 09:46:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+protocolSearcher
+
+    ^ self initializeSearcher: ProtocolSearcher
+
+    "Created: / 01-11-2014 / 15:56:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 03-11-2014 / 09:46:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+    "Searches for source code pattern in whole context which contains code, methods, classes...
+    and when context is from browser then restrict search within its perspective (CustomPerspective)."
+    | perspective |
+
+    perspective := aCustomContext perspective.
+
+    self class privateClassesDo: [ :class |
+        (class includesSelector: #search:inContext:withResultDo:) ifTrue: [ 
+            (perspective isNil or: [ class availableInPerspective: perspective ]) ifTrue: [ 
+                | searcher |
+
+                searcher := self initializeSearcher: class.
+                searcher search: searchPattern inContext: aCustomContext withResultDo: aBlock    
+            ]
+        ]
+    ]
+
+    "Created: / 17-08-2014 / 16:21:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 05-11-2014 / 20:33:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-12-2014 / 22:41:52 / root"
+! !
+
+!CustomRefactoryBuilder::ClassCategorySearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+    "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+    ^ aCustomPerspective isClassCategoryPerspective
+
+    "Created: / 04-11-2014 / 18:44:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ClassCategorySearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+    "Iterates through all classes to find out which belongs to given categories and
+    executes search on those classes for methods matching given searchPattern."
+    | categories classSearcher |
+
+    categories := aCustomContext selectedClassCategories.
+    categories isEmptyOrNil ifTrue: [
+        "Skip search when none categories are selected.
+        The algorithm would iterate through all classes so this is an optimization."
+        ^ self
+    ].
+
+    classSearcher := self classSearcher.
+
+    model allClassesDo: [ :class |
+        "Including only non metaclasses, because search in class
+        searches both class and metaclass."
+        (class isMeta not and: [categories includes: class category]) ifTrue: [ 
+            classSearcher search: searchPattern inClass: class withResultDo: aBlock 
+        ]
+    ]
+
+    "Created: / 04-11-2014 / 18:42:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 20:55:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ClassSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+    "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+    ^ aCustomPerspective isClassPerspective
+
+    "Created: / 04-11-2014 / 21:39:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ClassSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inClass: aClass withResultDo: aBlock
+    "Searches through all methods from given class and metaclass."
+    | methodSearcher |
+
+    methodSearcher := self methodSearcher.
+
+    aClass instAndClassMethodsDo: [ :method |
+        methodSearcher search: searchPattern inMethod: method withResultDo: aBlock
+    ]
+
+    "Created: / 17-08-2014 / 13:15:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 20:57:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+    "Executes search on each class in selected class collection.
+    see search:inClass:withResultDo:"
+
+    aCustomContext selectedClasses ? #() do:[ :class | 
+        self search: searchPattern inClass: class withResultDo: aBlock
+    ].
+
+    "Created: / 04-11-2014 / 21:45:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::CodeSelectionSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+    "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+    ^ aCustomPerspective isCodeViewPerspective
+
+    "Created: / 04-11-2014 / 22:28:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::CodeSelectionSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+    "Searches for each selected code fragment (see CustomSourceCodeSelection)
+    which matches given search pattern.
+    If match is found then code selection is passed in a block."
+
+    aCustomContext selectedCodes ? #() do:[ :codeSelection | 
+        | parseTree selectedCode |
+
+        selectedCode := codeSelection selectedSourceCode.
+        selectedCode notEmptyOrNil ifTrue: [   
+            parseTree := self parseExpression: selectedCode.
+
+            (self searcher)
+                matches: searchPattern do: [ :aNode :answer |
+                    aBlock value: codeSelection  
+                ];
+                executeTree: parseTree
+        ]
+    ].
+
+    "Created: / 04-11-2014 / 22:26:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 16:15:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::MethodSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+    "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+    ^ aCustomPerspective isMethodPerspective
+
+    "Created: / 04-11-2014 / 22:29:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::MethodSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+    "Searches all selected methods and executes given block when match is found."
+
+    aCustomContext selectedMethods ? #() do: [ :method | 
+        self search: searchPattern inMethod: method withResultDo: aBlock
+    ].
+
+    "Created: / 04-11-2014 / 22:24:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+search: searchPattern inMethod: aMethod withResultDo: aBlock
+    | parseTree |
+
+    parseTree := aMethod parseTree.    
+
+    parseTree isNil ifTrue: [ 
+        self error: 'Cannot retrieve parseTree for method: ', aMethod asString.
+    ]
+    ifFalse: [
+        (self searcher)
+            matches: searchPattern do: [ :aNode :answer |
+                | selectedCodeResult |
+
+                selectedCodeResult := CustomSourceCodeSelection new
+                    selectedMethod: aMethod;  
+                    yourself.
+
+                aBlock value: selectedCodeResult  
+            ];
+            executeTree: parseTree
+    ].
+
+    "Created: / 16-08-2014 / 22:27:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 28-10-2014 / 09:45:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::PackageSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+    "see CustomRefactoryBuilder::ProtocolSearcher >> availableInPerspective:"
+
+    ^ aCustomPerspective isPackagePerspective
+
+    "Created: / 01-11-2014 / 16:46:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::PackageSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+    "Executes search on each method which belongs to selected packages.
+    see search:inMethod:withResultDo:"
+    | packages methodSearcher |
+
+    packages := aCustomContext selectedPackages.
+    packages isEmptyOrNil ifTrue: [
+        "Skip search when none packages are selected.
+        The algorithm would iterate through all classes so this is an optimization."
+        ^ self
+    ].
+
+    methodSearcher := self methodSearcher.
+
+    model allClassesDo: [ :class |
+        "Including only non metaclasses, because we use instAndClassMethodsDo:
+        and allClassesDo: have different implementations."
+        class isMeta ifFalse: [
+            class instAndClassMethodsDo: [ :method |
+                (packages includes: method package) ifTrue: [ 
+                    methodSearcher search: searchPattern inMethod: method withResultDo: aBlock 
+                ]
+            ]
+        ]
+    ]
+
+    "Created: / 01-11-2014 / 17:28:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 20:59:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ProtocolSearcher class methodsFor:'queries'!
+
+availableInPerspective:aCustomPerspective
+    "Returns true when perspective is desired type.
+    We need to limit the searching with respect to perspective,
+    because we need to search for example only in classes when we are in the class perspective
+    (the list of classes in the IDE - Tools::NewSystemBrowser)."
+
+    ^ aCustomPerspective isProtocolPerspective
+
+    "Created: / 29-10-2014 / 22:51:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder::ProtocolSearcher methodsFor:'searching - methods'!
+
+search: searchPattern inContext: aCustomContext withResultDo: aBlock
+    "Executes search on each method in selected protocols within selected classes.
+    see search:inMethod:withResultDo:"
+    | methodSearcher |
+
+    methodSearcher := self methodSearcher.
+
+    aCustomContext selectedClasses ? #() do:[ :class |
+        aCustomContext selectedProtocols ? #() do:[ :protocol |
+            class methodsDo:[ :method |
+                (protocol = (method category)) ifTrue:[
+                    methodSearcher search: searchPattern inMethod: method withResultDo: aBlock
+                ]
+            ]
+        ]
+    ]
+
+    "Created: / 29-10-2014 / 19:16:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 20:59:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilder class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoryBuilderTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,1923 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomRefactoryBuilderTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRefactoryBuilderTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomRefactoryBuilderTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+    ^ nil
+
+    "Created: / 24-08-2014 / 21:35:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilderTests methodsFor:'tests'!
+
+test_available_in_perspective_class_category
+    | perspective |
+
+    perspective := CustomPerspective classCategoryPerspective.
+
+    self assert: (refactoryBuilder classCategorySearcher class availableInPerspective:perspective)
+
+    "Modified: / 05-11-2014 / 20:20:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_class_searcher
+    | perspective |
+
+    perspective := CustomPerspective classPerspective.
+
+    self assert: (refactoryBuilder classSearcher class availableInPerspective:perspective)
+
+    "Modified: / 05-11-2014 / 20:21:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_code_selection_searcher
+    | perspective |
+
+    perspective := CustomPerspective codeViewPerspective.
+
+    self assert: (refactoryBuilder codeSelectionSearcher class availableInPerspective:perspective)
+
+    "Modified: / 05-11-2014 / 20:21:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_method_searcher
+    | perspective |
+
+    perspective := CustomPerspective methodPerspective.
+
+    self assert: (refactoryBuilder methodSearcher class availableInPerspective:perspective)
+
+    "Modified: / 05-11-2014 / 20:21:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_package_searcher    
+    | perspective |
+
+    perspective := CustomPerspective packagePerspective.
+
+    self assert: (refactoryBuilder packageSearcher class availableInPerspective:perspective)
+
+    "Modified: / 05-11-2014 / 20:21:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective_protocols
+    | perspective |
+
+    perspective := CustomPerspective protocolPerspective.
+    
+    self assert: (refactoryBuilder protocolSearcher class availableInPerspective:perspective)
+
+    "Modified: / 05-11-2014 / 20:21:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_category_of_to_model_class
+    | expectedCategory actualCategory class |
+
+    class := model createClass
+        name: #DummyClassForTestCase01; 
+        category: 'Category01';
+        compile;
+        yourself.
+
+    expectedCategory := 'Category02'.
+
+    refactoryBuilder changeCategoryOf: class to: 'Category02'.    
+
+    actualCategory := class category.
+    
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 08-11-2014 / 13:46:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_category_of_to_model_class_execute
+    | expectedCategory actualCategory class |
+
+    class := model createClass
+        name: #DummyClassForTestCase01; 
+        category: 'Category01';
+        compile;
+        yourself.
+
+    expectedCategory := 'Category02'.
+
+    refactoryBuilder changeCategoryOf: class to: 'Category02'; execute.    
+
+    actualCategory := (Smalltalk at: #DummyClassForTestCase01) category.
+    
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 08-11-2014 / 14:10:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 17:43:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_category_of_to_real_class
+    | expectedCategory actualCategory class |
+
+    class := model createClassImmediate: #DummyClassForTestCase01 category: 'Category01'.
+
+    expectedCategory := 'Category02'.
+
+    refactoryBuilder changeCategoryOf: class to: 'Category02'; execute.    
+
+    actualCategory := class category.
+    
+    self assert: expectedCategory = actualCategory
+
+    "Modified: / 08-11-2014 / 13:45:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_01
+    
+    |originalSource expectedSource actualSource codeSelection|
+
+    originalSource := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    expectedSource := 'selector
+    self information: (resources string:''Translate this'').
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedInterval: (32 to: 47);
+        selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+    refactoryBuilder executeReplace: '`@code' 
+        with: '(resources string: `@code)'
+        inCodeSelection: codeSelection.
+
+    refactoryBuilder model changes do: [ :change |
+        actualSource := change source
+    ].
+
+    self assertSource: expectedSource sameAs: actualSource.
+
+    "Created: / 25-08-2014 / 21:53:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 09-12-2014 / 22:22:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_02
+    
+    |originalSource expectedSource actualSource codeSelection|
+
+    originalSource := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    expectedSource := 'selector
+    resources string:(self information:''Translate this'').
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedInterval: (14 to: 47);
+        selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+    refactoryBuilder executeReplace: '`@code' 
+        with: '(resources string: `@code)'
+        inCodeSelection: codeSelection.
+
+    refactoryBuilder model changes do: [ :change |
+        actualSource := change source
+    ].
+
+    self assertSource: expectedSource sameAs: actualSource.
+
+    "Created: / 26-08-2014 / 22:37:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 17:52:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_03
+
+    |originalSource expectedSource actualSource codeSelection|
+
+    originalSource := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    expectedSource := 'selector
+    self information: ''Translate this''.
+    ^ resources string:self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedInterval: (55 to: 59);
+        selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+    refactoryBuilder executeReplace: '`@code' 
+        with: '(resources string: `@code)'
+        inCodeSelection: codeSelection.
+
+    refactoryBuilder model changes do: [ :change |
+        actualSource := change source
+    ].
+
+    self assertSource: expectedSource sameAs: actualSource.
+
+    "Created: / 26-08-2014 / 22:41:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 20:07:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_execute_replace_with_in_code_selection_04
+
+    |originalSource expectedSource actualSource codeSelection|
+
+    originalSource := 'selector
+    | temp |
+
+    temp := ''Translate this''.
+
+    self information: temp.
+    ^ self.'.
+
+    expectedSource := 'selector
+    | temp |
+
+    temp := ''Translate this''.
+
+    self information: (resources string:temp).
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: originalSource;
+        selectedInterval: (77 to: 81);
+        selectedMethod: (self class compiledMethodAt: #generatorOrRefactoring). "/ just some method
+
+    refactoryBuilder executeReplace: '`@code' 
+        with: '(resources string: `@code)'
+        inCodeSelection: codeSelection.
+
+    refactoryBuilder model changes do: [ :change |
+        actualSource := change source
+    ].
+
+    self assertSource: expectedSource sameAs: actualSource.
+
+    "Created: / 26-08-2014 / 22:52:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-12-2014 / 20:08:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_initialize_change_for_add_class
+    "/ something initializeChange:aChangeClass.    
+    | change |
+
+    change := refactoryBuilder initializeChange: AddClassChange.
+
+    self assert: (change class) == AddClassChange.
+    self assert: (change model) == (refactoryBuilder model)
+
+    "Modified: / 08-11-2014 / 16:12:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_class_with_result_do_class_with_methods
+    | class expectedResult actualResult |
+
+    class := model createClassImmediate: 'DummyClassForTestCase'.
+    model createMethodImmediate: class source: 'selector_01 ^ 1'.
+    model createMethodImmediate: class class source: 'selector_02 ^ 2'.
+
+    expectedResult := OrderedCollection new
+        add: (class compiledMethodAt: #selector_01);
+        add: (class class compiledMethodAt: #selector_02);
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder classSearcher search: '`@something' inClass: class withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedMethod
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 19-10-2014 / 16:56:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-11-2014 / 22:15:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_class_with_result_do_empty_class
+    | class expectedResult actualResult |
+
+    class := model createClassImmediate: 'DummyClassForTestCase'.  
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder classSearcher search: '`@something' inClass: class withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Modified: / 04-11-2014 / 22:19:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_class_with_result_do_model_class_with_methods
+    | class expectedResult actualResult |
+
+    class := model createClass
+        name: #DummyClassForTestCase;
+        compile;
+        yourself.
+    class compile: 'selector_01 ^ 1' classified: 'some protocol'.
+    class theMetaclass compile: 'selector_02 ^ 2' classified: 'some protocol'.
+
+    expectedResult := OrderedCollection new
+        add: (class compiledMethodAt: #selector_01);
+        add: (class theMetaclass compiledMethodAt: #selector_02);
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder classSearcher search: '`@something' inClass: class withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedMethod
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 19-10-2014 / 17:24:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-11-2014 / 22:19:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_different_with_class
+    | category01 class01 category02 class02 modelClass expectedResult actualResult |
+
+    category01 := 'Some-Non-Existing-Category01'.
+    category02 := 'Some-Non-Existing-Category02'.
+
+    class01 := model createClassImmediate: 'DummyClassForTestCase01' category: category01.
+    model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+    model createMethodImmediate: class01 class source: 'selector_02 ^ 2'.
+
+    class02 := model createClassImmediate: 'DummyClassForTestCase02' category: category02.
+    model createMethodImmediate: class02 source: 'selector_01X ^ 101'.
+    model createMethodImmediate: class02 class source: 'selector_02X ^ 202'. 
+
+    modelClass := model classFor: class01.
+
+    expectedResult := OrderedCollection new
+        add: (modelClass compiledMethodAt: #selector_01) selector;
+        add: (modelClass theMetaclass compiledMethodAt: #selector_02) selector;
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    context selectedClassCategories: (Array with: category01).  
+
+    refactoryBuilder classCategorySearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 21:27:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_empty_context
+    | expectedResult actualResult |
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder classCategorySearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Modified (comment): / 04-11-2014 / 20:50:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_empty_with_model_classes
+    | expectedResult actualResult class01 |
+
+    class01 := model createClass
+        name: #DummyClass01;
+        category: 'Some-Category01';
+        compile;
+        compile: 'selector_01 ^ 1';
+        compile: 'selector_02 ^ 2';
+        yourself.
+
+    model createClass
+        name: #DummyClass02;
+        category: 'Some-Category02';
+        compile;
+        compile: 'selector_03 ^ 3'.
+
+    model createClass
+        name: #DummyClass03;
+        compile;
+        compile: 'selector_04 ^ 4'.
+
+    context selectedClassCategories: (Array with:'Some-Category01').    
+
+    expectedResult := OrderedCollection new
+        add: (class01 compiledMethodAt:#selector_01);
+        add: (class01 compiledMethodAt:#selector_02);
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder classCategorySearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedMethod    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 05-11-2014 / 21:21:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:19:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_model_classes
+    | expectedResult actualResult class01 class03 |
+
+    class01 := model createClass
+        name: #DummyClass01;
+        category: 'Some-Category01';
+        compile;
+        compile: 'selector_01 ^ 1';
+        compile: 'selector_02 ^ 2';
+        yourself.
+
+    model createClass
+        name: #DummyClass02;
+        category: 'Some-Category02';
+        compile;
+        compile: 'selector_03 ^ 3'.
+
+    class03 := model createClass
+        name: #DummyClass03;
+        category: 'Some-Category03';
+        compile;
+        compile: 'selector_04 ^ 4';
+        yourself.
+
+    context selectedClassCategories: (Array with:'Some-Category01' with:'Some-Category03').    
+
+    expectedResult := OrderedCollection new
+        add: (class03 compiledMethodAt:#selector_04);
+        add: (class01 compiledMethodAt:#selector_01);
+        add: (class01 compiledMethodAt:#selector_02);
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder classCategorySearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedMethod    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 21:03:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:15:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_real_category
+    | actualResult |
+
+    actualResult := OrderedCollection new.
+
+    context selectedClassCategories: (Array with: self class category).  
+
+    refactoryBuilder classCategorySearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector
+    ].
+
+    self assert: actualResult size notEmptyOrNil
+
+    "Created: / 04-11-2014 / 21:18:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:03:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_categories_with_class
+    | category class modelClass expectedResult actualResult |
+
+    category := 'Some-Non-Existing-Category01'.
+    class := model createClassImmediate: 'DummyClassForTestCase' category: category.
+    model createMethodImmediate: class source: 'selector_01 ^ 1'.
+    model createMethodImmediate: class class source: 'selector_02 ^ 2'.
+
+    modelClass := model classFor: class.
+    self assert: modelClass == (model classFor: class).  
+
+    expectedResult := OrderedCollection new
+        add: (modelClass compiledMethodAt: #selector_01) selector;
+        add: (modelClass theMetaclass compiledMethodAt: #selector_02) selector;
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    context selectedClassCategories: (Array with: category).  
+
+    refactoryBuilder classCategorySearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 21:32:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_classes    
+    | class01 class02 modelClass01 modelClass02 expectedResult actualResult |
+
+    class01 := model createClassImmediate: 'DummyClassForTestCase01'.
+    model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+    model createMethodImmediate: class01 class source: 'selector_02 ^ 2'.
+
+    class02 := model createClassImmediate: 'DummyClassForTestCase02'.
+    model createMethodImmediate: class02 source: 'selector_01X ^ 101'.
+    model createMethodImmediate: class02 class source: 'selector_02X ^ 202'. 
+
+    modelClass01 := model classFor: class01.
+    modelClass02 := model classFor: class02.
+
+    expectedResult := OrderedCollection new
+        add: (modelClass01 compiledMethodAt: #selector_01) selector;
+        add: (modelClass01 theMetaclass compiledMethodAt: #selector_02) selector;
+        add: (modelClass02 compiledMethodAt: #selector_01X) selector;
+        add: (modelClass02 theMetaclass compiledMethodAt: #selector_02X) selector;
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    context selectedClasses:(Array with: class01 with: class02).   
+
+    refactoryBuilder classSearcher search:'`@something' inContext:context withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 21:59:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_classes_empty_context    
+    | expectedResult actualResult |
+
+    actualResult := OrderedCollection new.
+    expectedResult := OrderedCollection new.
+
+    refactoryBuilder classSearcher search:'`@something' inContext:context withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 22:06:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_empty_browser_context
+    | browserContext expectedResult actualResult |
+
+    browserContext := CustomBrowserContext
+        perspective: CustomPerspective new 
+        state: Tools::NavigationState new.
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:browserContext withResultDo:[ :method |
+        actualResult add: method selector    
+    ].    
+    
+    self assert: expectedResult = actualResult.
+
+    "Modified (format): / 25-10-2014 / 21:00:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_empty_code_selection
+    | expectedResult actualResult |
+
+    context selectedCodes: {CustomSourceCodeSelection new}.  
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder codeSelectionSearcher search:'`@something' inContext:context withResultDo:[ :method |
+        actualResult add: method selector    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Modified: / 04-01-2015 / 16:13:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_empty_sub_context
+    | expectedResult actualResult |
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:context withResultDo:[ :method |
+        actualResult add: method selector    
+    ].    
+    
+    self assert: expectedResult = actualResult.
+
+    "Created: / 25-10-2014 / 21:01:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 19:08:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_class_category_perspective
+    | expectedResult actualResult class02 class03 method03 
+    codeSelection class04 class05 method05 class06 |
+
+    model createClass 
+        name: #DummyClassForTestCase01; 
+        category: 'Some-Test-Category01';
+        compile;
+        compile: 'selector_01 ^ 1'.
+
+    class02 := model createClass
+        name: #DummyClassForTestCase02;
+        compile;
+        compile: 'selector_02 ^ 2';
+        yourself.
+
+    class03 := model createClass
+        name: #DummyClassForTestCase03;
+        compile;
+        yourself.
+
+    method03 := model createMethod
+        class: class03; 
+        source: 'selector_03 ^ self';
+        compile;
+        yourself.
+
+    self assert: #selector_03 = (method03 selector).
+
+    codeSelection := CustomSourceCodeSelection new
+        selectedMethod: method03;
+        selectedInterval: (15 to: 18);
+        yourself.
+
+    self assert: 'self' = (codeSelection selectedSourceCode).  
+
+    class04 := model createClass
+        name: #DummyClassForTestCase04;
+        compile;
+        compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+        yourself.
+
+    class05 := model createClass
+        name: #DummyClassForTestCase05;
+        compile;
+        yourself.
+
+    method05 := model createMethod
+        class: class05; 
+        source: 'selector_05 ^ 5';
+        compile;
+        yourself. 
+
+    class06 := model createClass
+        name: #DummyClassForTestCase06;
+        compile;
+        yourself.
+
+    model createMethod
+        class: class06; 
+        source: 'selector_06 ^ 6';
+        package: #some_package01;
+        compile. 
+
+    context := mock mockOf: CustomSubContext.
+    context
+        compileMockMethod: 'perspective ^ CustomPerspective classCategoryPerspective';
+        selectedClassCategories: (Array with: 'Some-Test-Category01');
+        selectedClasses: (Array with: class02 with: class04);
+        selectedCodes: (Array with: codeSelection);
+        selectedProtocols: (Array with: 'method protocol 01');
+        selectedMethods: (Array with: method05);
+        selectedPackages: (Array with: #some_package01).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        | selector |
+
+        selector := sourceSelection selectedSelector.
+        self assert: selector notNil.
+
+        actualResult add: selector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+    
+    self assert: expectedResult = actualResult.
+
+    "Created: / 05-11-2014 / 22:04:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:15:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_class_perspective
+    | expectedResult actualResult class02 class03 method03 
+    codeSelection class04 class05 method05 class06 |
+
+    model createClass 
+        name: #DummyClassForTestCase01; 
+        category: 'Some-Test-Category01';
+        compile;
+        compile: 'selector_01 ^ 1'.
+
+    class02 := model createClass
+        name: #DummyClassForTestCase02;
+        compile;
+        compile: 'selector_02 ^ 2';
+        yourself.
+
+    class03 := model createClass
+        name: #DummyClassForTestCase03;
+        compile;
+        yourself.
+
+    method03 := model createMethod
+        class: class03; 
+        source: 'selector_03 ^ self';
+        compile;
+        yourself.
+
+    self assert: #selector_03 = (method03 selector).
+
+    codeSelection := CustomSourceCodeSelection new
+        selectedMethod: method03;
+        selectedInterval: (15 to: 18);
+        yourself.
+
+    self assert: 'self' = (codeSelection selectedSourceCode).  
+
+    class04 := model createClass
+        name: #DummyClassForTestCase04;
+        compile;
+        compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+        yourself.
+
+    class05 := model createClass
+        name: #DummyClassForTestCase05;
+        compile;
+        yourself.
+
+    method05 := model createMethod
+        class: class05; 
+        source: 'selector_05 ^ 5';
+        compile;
+        yourself. 
+
+    class06 := model createClass
+        name: #DummyClassForTestCase06;
+        compile;
+        yourself.
+
+    model createMethod
+        class: class06; 
+        source: 'selector_06 ^ 6';
+        package: #some_package01;
+        compile. 
+
+    context := mock mockOf: CustomSubContext.
+    context
+        compileMockMethod: 'perspective ^ CustomPerspective classPerspective';
+        selectedClassCategories: (Array with: 'Some-Test-Category01');
+        selectedClasses: (Array with: class02 with: class04);
+        selectedCodes: (Array with: codeSelection);
+        selectedProtocols: (Array with: 'method protocol 01');
+        selectedMethods: (Array with: method05);
+        selectedPackages: (Array with: #some_package01).
+
+    expectedResult := OrderedCollection new
+        add: #selector_02;
+        add: #selector_04;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        | selector |
+
+        selector := sourceSelection selectedSelector.
+        self assert: selector notNil.
+
+        actualResult add: selector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+    
+    self assert: expectedResult = actualResult.
+
+    "Created: / 05-11-2014 / 22:02:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:15:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_package_perspective
+    | expectedResult actualResult class02 class03 method03 
+    codeSelection class04 class05 method05 class06 |
+
+    model createClass 
+        name: #DummyClassForTestCase01; 
+        category: 'Some-Test-Category01';
+        compile;
+        compile: 'selector_01 ^ 1'.
+
+    class02 := model createClass
+        name: #DummyClassForTestCase02;
+        compile;
+        compile: 'selector_02 ^ 2';
+        yourself.
+
+    class03 := model createClass
+        name: #DummyClassForTestCase03;
+        compile;
+        yourself.
+
+    method03 := model createMethod
+        class: class03; 
+        source: 'selector_03 ^ self';
+        compile;
+        yourself.
+
+    self assert: #selector_03 = (method03 selector).
+
+    codeSelection := CustomSourceCodeSelection new
+        selectedMethod: method03;
+        selectedInterval: (15 to: 18);
+        yourself.
+
+    self assert: 'self' = (codeSelection selectedSourceCode).  
+
+    class04 := model createClass
+        name: #DummyClassForTestCase04;
+        compile;
+        compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+        yourself.
+
+    class05 := model createClass
+        name: #DummyClassForTestCase05;
+        compile;
+        yourself.
+
+    method05 := model createMethod
+        class: class05; 
+        source: 'selector_05 ^ 5';
+        compile;
+        yourself. 
+
+    class06 := model createClass
+        name: #DummyClassForTestCase06;
+        compile;
+        yourself.
+
+    model createMethod
+        class: class06; 
+        source: 'selector_06 ^ 6';
+        package: #some_package01;
+        compile. 
+
+    context := mock mockOf: CustomSubContext.
+    context
+        compileMockMethod: 'perspective ^ CustomPerspective packagePerspective';
+        selectedClassCategories: (Array with: 'Some-Test-Category01');
+        selectedClasses: (Array with: class02 with: class04);
+        selectedCodes: (Array with: codeSelection);
+        selectedProtocols: (Array with: 'method protocol 01');
+        selectedMethods: (Array with: method05);
+        selectedPackages: (Array with: #some_package01).
+
+    expectedResult := OrderedCollection new
+        add: #selector_06;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        | selector |
+
+        selector := sourceSelection selectedSelector.
+        self assert: selector notNil.
+
+        actualResult add: selector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+    
+    self assert: expectedResult = actualResult.
+
+    "Created: / 05-11-2014 / 22:06:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:15:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_browser_context_with_protocol_perspective
+    | expectedResult actualResult class02 class03 method03 
+    codeSelection class04 class05 method05 class06 |
+
+    model createClass 
+        name: #DummyClassForTestCase01; 
+        category: 'Some-Test-Category01';
+        compile;
+        compile: 'selector_01 ^ 1'.
+
+    class02 := model createClass
+        name: #DummyClassForTestCase02;
+        compile;
+        compile: 'selector_02 ^ 2';
+        yourself.
+
+    class03 := model createClass
+        name: #DummyClassForTestCase03;
+        compile;
+        yourself.
+
+    method03 := model createMethod
+        class: class03; 
+        source: 'selector_03 ^ self';
+        compile;
+        yourself.
+
+    self assert: #selector_03 = (method03 selector).
+
+    codeSelection := CustomSourceCodeSelection new
+        selectedMethod: method03;
+        selectedInterval: (15 to: 18);
+        yourself.
+
+    self assert: 'self' = (codeSelection selectedSourceCode).  
+
+    class04 := model createClass
+        name: #DummyClassForTestCase04;
+        compile;
+        compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+        yourself.
+
+    class05 := model createClass
+        name: #DummyClassForTestCase05;
+        compile;
+        yourself.
+
+    method05 := model createMethod
+        class: class05; 
+        source: 'selector_05 ^ 5';
+        compile;
+        yourself. 
+
+    class06 := model createClass
+        name: #DummyClassForTestCase06;
+        compile;
+        yourself.
+
+    model createMethod
+        class: class06; 
+        source: 'selector_06 ^ 6';
+        package: #some_package01;
+        compile. 
+
+    context := mock mockOf: CustomSubContext.
+    context
+        compileMockMethod: 'perspective ^ CustomPerspective protocolPerspective';
+        selectedClassCategories: (Array with: 'Some-Test-Category01');
+        selectedClasses: (Array with: class02 with: class04);
+        selectedCodes: (Array with: codeSelection);
+        selectedProtocols: (Array with: 'method protocol 01');
+        selectedMethods: (Array with: method05);
+        selectedPackages: (Array with: #some_package01).
+
+    expectedResult := OrderedCollection new
+        add: #selector_04;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        | selector |
+
+        selector := sourceSelection selectedSelector.
+        self assert: selector notNil.
+
+        actualResult add: selector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+    
+    self assert: expectedResult = actualResult.
+
+    "Created: / 05-11-2014 / 22:05:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:15:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_sub_context
+    | expectedResult actualResult class01 class02 class03 method03 
+    codeSelection class04 class05 method05 class06 |
+
+    class01 := model createClassImmediate: #DummyClassForTestCase01 category: 'Some-Test-Category01'.
+    model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+
+    class02 := model createClassImmediate: #DummyClassForTestCase02.
+    model createMethodImmediate: class02 source: 'selector_02 ^ 2'. 
+
+    class03 := model createClassImmediate: #DummyClassForTestCase03.
+    method03 := model createMethodImmediate: class03 source: 'selector_03 ^ self'.
+    self assert: #selector_03 = (method03 selector).
+
+    codeSelection := CustomSourceCodeSelection new
+        selectedMethod: method03;
+        selectedInterval: (15 to: 18);
+        yourself.
+
+    self assert: 'self' = (codeSelection selectedSourceCode).  
+
+    class04 := model createClassImmediate: #DummyClassForTestCase04.
+    model createMethodImmediate: class04 protocol: 'method protocol 01' source: 'selector_04 ^ 4'.
+
+    class05 := model createClassImmediate: #DummyClassForTestCase05.
+    method05 := model createMethodImmediate: class05 source: 'selector_05 ^ 5'. 
+
+    class06 := model createClassImmediate: #DummyClassForTestCase06.
+    (model createMethodImmediate: class06 source: 'selector_06 ^ 6')
+        package: #some_package01. 
+
+    context 
+        selectedClassCategories: (Array with: 'Some-Test-Category01');
+        selectedClasses: (Array with: class02 with: class04);
+        selectedCodes: (Array with: codeSelection);
+        selectedProtocols: (Array with: 'method protocol 01');
+        selectedMethods: (Array with: method05);
+        selectedPackages: (Array with: #some_package01).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_02;
+        add: #selector_03;
+        add: #selector_04;
+        add: #selector_04;
+        add: #selector_05;
+        add: #selector_06;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        | selector |
+
+        selector := sourceSelection selectedSelector.
+        self assert: selector notNil.
+
+        actualResult add: selector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+    
+    self assert: expectedResult = actualResult.
+
+    "Created: / 25-10-2014 / 21:05:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 21:02:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_filled_sub_context_model_classes
+    | expectedResult actualResult class02 class03 method03 
+    codeSelection class04 class05 method05 class06 |
+
+    model createClass 
+        name: #DummyClassForTestCase01; 
+        category: 'Some-Test-Category01';
+        compile;
+        compile: 'selector_01 ^ 1'.
+
+    class02 := model createClass
+        name: #DummyClassForTestCase02;
+        compile;
+        compile: 'selector_02 ^ 2';
+        yourself.
+
+    class03 := model createClass
+        name: #DummyClassForTestCase03;
+        compile;
+        yourself.
+
+    method03 := model createMethod
+        class: class03; 
+        source: 'selector_03 ^ self';
+        compile;
+        yourself.
+
+    self assert: #selector_03 = (method03 selector).
+
+    codeSelection := CustomSourceCodeSelection new
+        selectedMethod: method03;
+        selectedInterval: (15 to: 18);
+        yourself.
+
+    self assert: 'self' = (codeSelection selectedSourceCode).  
+
+    class04 := model createClass
+        name: #DummyClassForTestCase04;
+        compile;
+        compile: 'selector_04 ^ 4' classified: 'method protocol 01';
+        yourself.
+
+    class05 := model createClass
+        name: #DummyClassForTestCase05;
+        compile;
+        yourself.
+
+    method05 := model createMethod
+        class: class05; 
+        source: 'selector_05 ^ 5';
+        compile;
+        yourself. 
+
+    class06 := model createClass
+        name: #DummyClassForTestCase06;
+        compile;
+        yourself.
+
+    model createMethod
+        class: class06; 
+        source: 'selector_06 ^ 6';
+        package: #some_package01;
+        compile. 
+
+    context 
+        selectedClassCategories: (Array with: 'Some-Test-Category01');
+        selectedClasses: (Array with: class02 with: class04);
+        selectedCodes: (Array with: codeSelection);
+        selectedProtocols: (Array with: 'method protocol 01');
+        selectedMethods: (Array with: method05);
+        selectedPackages: (Array with: #some_package01).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_02;
+        add: #selector_03;
+        add: #selector_04;
+        add: #selector_04;
+        add: #selector_05;
+        add: #selector_06;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        | selector |
+
+        selector := sourceSelection selectedSelector.
+        self assert: selector notNil.
+
+        actualResult add: selector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+    
+    self assert: expectedResult = actualResult.
+
+    "Created: / 05-11-2014 / 21:11:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:16:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_01
+    | expectedResult actualResult class01 method |
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    method := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+
+    context selectedMethods:(Array with:method).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 22:55:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_02
+    | expectedResult actualResult class01 method01 method02 |
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    method01 := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+    method02 := self class compiledMethodAt:#test_search_in_context_with_result_do_methods_02.
+
+    context selectedMethods:(Array with:method01 with:method02).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #test_search_in_context_with_result_do_methods_02;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 22:59:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_03
+    | expectedResult actualResult class01 method01 method02 |
+    
+    class01 := model createClass
+        name: #DummyClassForTestCase01;
+        compile;
+        compile: 'selector_01 ^ 1';
+        yourself.
+
+    method01 := class01 compiledMethodAt:#selector_01.  
+    method02 := model createMethod
+        class: class01;
+        source: 'selector_02 ^ 2';
+        compile;
+        yourself.
+
+    context selectedMethods:(Array with:method01 with:method02).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_02;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 23:05:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_methods_empty_context
+    | expectedResult actualResult |
+
+    actualResult := OrderedCollection new.
+    expectedResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search: '`@something' inContext: context withResultDo: [ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector
+    ].
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 22:52:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_01
+    | expectedResult actualResult class01 method |
+    
+    class01 := (model createClassImmediate: #DummyClassForTestCase01)
+        package: #some_package01;
+        yourself.
+
+    method := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+    method package: #some_package01.
+
+    context
+        selectedPackages:(Array with:#some_package01).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 01-11-2014 / 20:14:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 02-11-2014 / 13:31:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_02
+    |expectedResult actualResult class01 method01 method03 method04 method05 class02 method07 method08|
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    method01 := model createMethodImmediate: class01 source: 'selector_01 ^ 1'.
+    method01 package: #some_package01.
+    model createMethodImmediate: class01 source: 'selector_02 ^ 2'.
+    method03 := model createMethodImmediate: class01 source: 'selector_03 ^ 3'.
+    method03 package: #some_package03.
+    method04 := model createMethodImmediate: class01 class source: 'selector_04 ^ 4'.
+    method04 package: #some_package02.
+    method05 := model createMethodImmediate: class01 source: 'selector_05 ^ 5'.
+    method05 package: #some_package01.
+
+    class02 := model createClassImmediate: #DummyClassForTestCase02.
+    model createMethodImmediate: class02 class source: 'selector_06 ^ 6'.
+    method07 := model createMethodImmediate: class02 class source: 'selector_07 ^ 7'.
+    method07 package: #some_package02.                              
+    method08 := model createMethodImmediate: class02 class source: 'selector_08 ^ 8'.
+    method08 package: #some_package03.                              
+
+    context
+        selectedPackages:(Array with:#some_package01 with:#some_package02).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_04;
+        add: #selector_05;
+        add: #selector_07;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 02-11-2014 / 11:58:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:53:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_03
+    |expectedResult actualResult class01 class02|
+    
+    class01 := model createClass
+        name: #DummyClassForTestCase01;
+        compile;
+        yourself.
+
+    model createMethod class: class01; source: 'selector_01 ^ 1'; package: #some_package01; compile.
+    model createMethod class: class01; source: 'selector_02 ^ 2'; compile.
+    model createMethod class: class01; source: 'selector_03 ^ 3'; package: #some_package03; compile.
+    model createMethod class: class01 theMetaclass; source: 'selector_04 ^ 4'; package: #some_package02; compile.
+    model createMethod class: class01; source: 'selector_05 ^ 5'; package: #some_package01; compile.
+
+    class02 := model createClass
+        name: #DummyClassForTestCase02;
+        compile;
+        yourself.
+
+    model createMethod class: class02 theMetaclass; source: 'selector_06 ^ 6'; compile.
+    model createMethod class: class02 theMetaclass; source: 'selector_07 ^ 7'; package: #some_package02; compile.                              
+    model createMethod class: class02 theMetaclass; source: 'selector_08 ^ 8'; package: #some_package03; compile.                              
+    model createMethod class: class02; source: 'selector_09 ^ 9'; package: #some_package01; compile.                              
+
+    context
+        selectedPackages:(Array with:#some_package01 with:#some_package02).
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_04;
+        add: #selector_05;
+        add: #selector_07;        
+        add: #selector_09;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 02-11-2014 / 16:52:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-11-2014 / 01:12:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_packages_empty_context
+    | expectedResult actualResult |
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder packageSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 02-11-2014 / 11:57:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_01
+    | expectedResult actualResult class01 |
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+
+    context
+        selectedClasses:(Array with:class01);  
+        selectedProtocols:(Array with:'method protocol 01').
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Modified: / 01-11-2014 / 16:28:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_02
+    | expectedResult actualResult class01 |
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+    model createMethodImmediate: class01 protocol: 'method protocol 02' source: 'selector_02 ^ 2' .
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_03 ^ 3' .
+
+    context
+        selectedClasses:(Array with:class01);  
+        selectedProtocols:(Array with:'method protocol 01').
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_03;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 01-11-2014 / 16:29:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_03
+    | expectedResult actualResult class01 class02 |
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+    model createMethodImmediate: class01 protocol: 'method protocol 02' source: 'selector_02 ^ 2' .
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_03 ^ 3' .
+
+    class02 := model createClassImmediate: #DummyClassForTestCase02.
+    model createMethodImmediate: class02 protocol: 'method protocol 02' source: 'selector_04 ^ 4' .
+
+    context
+        selectedClasses:(Array with:class01 with:class02);  
+        selectedProtocols:(Array with:'method protocol 01').
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_03;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 01-11-2014 / 16:34:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_04
+    | expectedResult actualResult class01 class02 |
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+    model createMethodImmediate: class01 protocol: 'method protocol 02' source: 'selector_02 ^ 2' .
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_03 ^ 3' .
+
+    class02 := model createClassImmediate: #DummyClassForTestCase02.
+    model createMethodImmediate: class02 protocol: 'method protocol 02' source: 'selector_04 ^ 4' .
+    model createMethodImmediate: class02 protocol: 'method protocol 01' source: 'selector_05 ^ 5' .
+
+    context
+        selectedClasses:(Array with:class01 with:class02);  
+        selectedProtocols:(Array with:'method protocol 01').
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        add: #selector_03;        
+        add: #selector_05;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 01-11-2014 / 16:36:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_empty_classes
+    | expectedResult actualResult class01 |
+    
+    class01 := model createClassImmediate: #DummyClassForTestCase01.
+    model createMethodImmediate: class01 protocol: 'method protocol 01' source: 'selector_01 ^ 1' .
+
+    context
+        selectedProtocols:(Array with:'method protocol 01').
+
+    expectedResult := OrderedCollection new
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 01-11-2014 / 17:07:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_empty_context
+    | expectedResult actualResult |
+
+    expectedResult := OrderedCollection new
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 01-11-2014 / 17:08:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_protocols_model_classes
+    | expectedResult actualResult class01 |
+    
+    class01 := model createClass
+        name: #DummyClassForTestCase01;
+        compile;
+        compile: 'selector_01 ^ 1' classified: 'method protocol 01';
+        yourself.
+
+    context
+        selectedClasses:(Array with:class01);  
+        selectedProtocols:(Array with:'method protocol 01').
+
+    expectedResult := OrderedCollection new
+        add: #selector_01;
+        asSortedCollection.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder protocolSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    actualResult := actualResult asSortedCollection.
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 01-11-2014 / 16:41:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_01
+    |source codeSelection resultsFoundCount |
+
+    source := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: source;
+        selectedInterval: (32 to: 47).
+
+    resultsFoundCount := 0.
+
+    context selectedCodes: (Array with: codeSelection).  
+
+    refactoryBuilder codeSelectionSearcher search: '`@code' 
+        inContext: context 
+        withResultDo: [ :codeSelection |
+            resultsFoundCount := resultsFoundCount + 1
+        ].
+
+    self assert: resultsFoundCount = 1.
+
+    "Created: / 04-11-2014 / 23:27:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 18:40:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_02
+    |source codeSelection resultsFoundCount |
+
+    source := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: source;
+        selectedInterval: (32 to: 47).
+
+    resultsFoundCount := 0.
+
+    context selectedCodes: (Array with: codeSelection).  
+
+    refactoryBuilder codeSelectionSearcher search: '`#literal' 
+        inContext: context 
+        withResultDo: [ :codeSelection |
+            resultsFoundCount := resultsFoundCount + 1
+        ].
+
+    self assert: resultsFoundCount = 1.
+
+    "Created: / 04-11-2014 / 23:28:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 18:41:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_03
+    |source codeSelection resultsFoundCount |
+
+    source := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: source;
+        selectedInterval: (1 to: source size).
+
+    resultsFoundCount := 0.
+
+    context selectedCodes: (Array with: codeSelection).    
+
+    refactoryBuilder codeSelectionSearcher search: '`#literal' 
+        inContext: context
+        withResultDo: [ :codeSelection |
+            resultsFoundCount := resultsFoundCount + 1
+        ].
+
+    self assert: resultsFoundCount = 1.
+
+    "Created: / 04-11-2014 / 23:28:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 18:37:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_04
+    |source codeSelection resultsFoundCount |
+
+    source := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: source;
+        selectedInterval: (14 to: 51).
+
+    resultsFoundCount := 0.
+
+    context selectedCodes: (Array with: codeSelection).  
+
+    refactoryBuilder codeSelectionSearcher search: '`@code' 
+        inContext: context 
+        withResultDo: [ :codeSelection |
+            resultsFoundCount := resultsFoundCount + 1
+        ].
+
+    self assert: resultsFoundCount = 1.
+
+    "Created: / 04-11-2014 / 23:28:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_05
+    |source codeSelection resultsFoundCount |
+
+    source := 'selector
+    self information: ''Translate this''.
+    ^ self.'.
+
+    codeSelection := CustomSourceCodeSelection new.
+    codeSelection
+        currentSourceCode: source;
+        selectedInterval: (30 to: 38).
+
+    resultsFoundCount := 0.
+
+    context selectedCodes: (Array with: codeSelection).  
+
+    self should: [ 
+        refactoryBuilder codeSelectionSearcher search: '`@code' 
+            inContext: context 
+            withResultDo: [ :codeSelection |
+                resultsFoundCount := resultsFoundCount + 1
+            ].
+    ] raise: Error.
+
+    "Created: / 04-11-2014 / 23:29:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_context_with_result_do_selected_codes_empty_context
+    | expectedResult actualResult |
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder codeSelectionSearcher search:'`@something' inContext:context withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedSelector    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Modified: / 04-11-2014 / 23:26:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_model_method_01
+    |expectedResult actualResult method|
+
+    method := model createMethod
+        source:'selector_01 ^ 1';
+        yourself.
+
+    expectedResult := OrderedCollection new
+        add:method;
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search:'`@something' inMethod:method withResultDo:[ :sourceSelection | 
+        actualResult add:sourceSelection selectedMethod 
+    ].
+
+    self assert:expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 23:15:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_model_method_02
+    | expectedResult actualResult method |
+
+    method := model createMethod
+        source: 'selector_01 ^ 1';
+        yourself. 
+
+    expectedResult := OrderedCollection new
+        add: method;
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search:'`#literal' inMethod:method withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedMethod    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 23:16:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_model_method_03
+    |expectedResult actualResult method|
+
+    method := model createMethod
+        source:'selector_01 ^ self';
+        yourself.
+
+    expectedResult := OrderedCollection new.
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search:'`#literal' inMethod:method withResultDo:[ :sourceSelection | 
+        actualResult add:sourceSelection selectedMethod 
+    ].
+
+    self assert:expectedResult = actualResult.
+
+    "Created: / 04-11-2014 / 23:19:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_search_in_method_with_result_do_real_method
+    | expectedResult actualResult class method |
+
+    class := model createClassImmediate: #DummyClass01.
+    method := model createMethodImmediate: class source: 'selector_01 ^ 1'. 
+
+    expectedResult := OrderedCollection new
+        add: method;
+        yourself.
+
+    actualResult := OrderedCollection new.
+
+    refactoryBuilder methodSearcher search:'`@something' inMethod:method withResultDo:[ :sourceSelection |
+        actualResult add: sourceSelection selectedMethod    
+    ].    
+
+    self assert: expectedResult = actualResult.
+
+    "Modified: / 04-11-2014 / 23:14:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryBuilderTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomRefactoryClassChangeTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,175 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomRefactoryClassChangeTests
+	instanceVariableNames:'change model'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomRefactoryClassChangeTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomRefactoryClassChangeTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    model := RBNamespace new.
+    change := RefactoryClassChange new
+        model: model;
+        yourself.
+
+    "Modified: / 08-11-2014 / 14:29:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomRefactoryClassChangeTests methodsFor:'tests'!
+
+test_change_class_with_existing_class
+    | expectedClass actualClass |
+
+    change changeClass: self class.
+
+    expectedClass := self class.
+    actualClass := change changeClass.
+
+    self assert: expectedClass == actualClass
+
+    "Created: / 08-11-2014 / 14:35:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_existing_class_with_rb_class
+    | expectedClass actualClass rbClass |
+
+    rbClass := model classFor: self class.  
+
+    change changeClass: rbClass.
+
+    expectedClass := self class.
+    actualClass := change changeClass.
+
+    self assert: expectedClass == actualClass
+
+    "Created: / 08-11-2014 / 14:36:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_existing_metaclass
+    | expectedClass actualClass |
+
+    change changeClass: self class class.
+
+    expectedClass := self class class.
+    actualClass := change changeClass.
+
+    self assert: expectedClass == actualClass
+
+    "Created: / 08-11-2014 / 14:35:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_non_existing_class
+    | expectedClass actualClass |
+
+    change model: nil.
+
+    change changeClass: (RBClass new
+        name: #DummyClass01;
+        yourself).
+
+    self assert: (Smalltalk at: #DummyClass01) isNil.
+
+    expectedClass := nil.
+    actualClass := change changeClass.
+
+    self assert: expectedClass == actualClass
+
+    "Created: / 08-11-2014 / 14:38:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_non_existing_class_but_model_class
+    | expectedClass actualClass class |
+
+    model defineClass: 'Object subclass:#DummyClassForTestCase01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    self assert: (Smalltalk at: #DummyClassForTestCase01) isNil.
+
+    class := model classNamed: #DummyClassForTestCase01.
+
+    change changeClass: class.
+
+    expectedClass := class.
+    actualClass := change changeClass.
+
+    self assert: expectedClass == actualClass
+
+    "Created: / 08-11-2014 / 14:27:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_change_class_with_non_existing_metaclass_but_model_metaclass
+    | expectedClass actualClass class |
+
+    model defineClass: 'Object subclass:#DummyClassForTestCase01
+        instanceVariableNames:''''
+        classVariableNames:''''
+        poolDictionaries:''''
+        category:'''''.
+
+    self assert: (Smalltalk at: #DummyClassForTestCase01) isNil.
+
+    class := model metaclassNamed: #DummyClassForTestCase01.
+
+    change changeClass: class.
+
+    expectedClass := class.
+    actualClass := change changeClass.
+
+    self assert: expectedClass == actualClass
+
+    "Created: / 08-11-2014 / 14:33:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomRefactoring subclass:#CustomReplaceIfNilWithIfTrueRefactoring
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Search for ifNil:ifNotNil: expressions and replace it with isNil ifTrue:ifFalse: expression'
+
+    "Created: / 07-08-2014 / 21:50:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Replace ifNil:ifNotNil: with isNil ifTrue:ifFalse:'
+
+    "Created: / 07-08-2014 / 21:51:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ true
+
+    "Created: / 07-08-2014 / 21:01:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    ^ true
+
+    "Created: / 07-08-2014 / 22:14:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Performs a refactoring within given context scope"
+
+    refactoryBuilder
+        replace: '``@receiver ifNil: ``@nilBlock ifNotNil: ``@notNilBlock'
+        with: '``@receiver isNil ifTrue: ``@nilBlock ifFalse: ``@notNilBlock'
+        inContext: aCustomContext
+
+    "Created: / 23-08-2014 / 00:17:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoring class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomReplaceIfNilWithIfTrueRefactoringTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,112 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomReplaceIfNilWithIfTrueRefactoringTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings-Tests'
+!
+
+!CustomReplaceIfNilWithIfTrueRefactoringTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoringTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomReplaceIfNilWithIfTrueRefactoring new
+! !
+
+!CustomReplaceIfNilWithIfTrueRefactoringTests methodsFor:'tests'!
+
+test_available_in_context
+    
+    "Available for every context"
+    self assert: (generatorOrRefactoring class availableInContext: context).
+
+    "Modified: / 16-10-2014 / 21:36:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+
+    "Available for every perspective"
+    self assert: (generatorOrRefactoring class availableInContext: CustomPerspective instance).
+
+    "Modified: / 16-10-2014 / 21:38:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_if_nil_replaced_with_is_nil_if_true
+    | expectedSource class |
+
+    class := model createClassImmediate: 'DummyClassForTestCase01'.
+    model createMethod
+        class: class;
+        protocol: 'protocol';
+        source: 'selector: arg
+        arg ifNil: [ 
+            self warn: ''nil''.
+        ]
+        ifNotNil: [ self information: ''info'' ].
+        ';
+        compile.
+
+    context selectedClasses: (Array with: class).  
+    model execute.
+
+    generatorOrRefactoring executeInContext: context.
+
+    expectedSource := 'selector:arg 
+    arg isNil ifTrue:[
+        self warn:''nil''.
+    ] ifFalse:[
+        self information:''info''
+    ].'.
+
+    self assertMethodSource: expectedSource atSelector: #selector: forClass: class.
+
+    "Created: / 10-08-2014 / 09:42:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-10-2014 / 19:02:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 25-01-2015 / 15:17:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSilentDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,187 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomDialog subclass:#CustomSilentDialog
+	instanceVariableNames:'methodAnswers'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-UI'
+!
+
+CustomSilentDialog subclass:#NilComponent
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:CustomSilentDialog
+!
+
+!CustomSilentDialog class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    CustomDialog implementation based on non human interaction with dialog answers.
+    You may set dialog aswers to inject them in code generators.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomSilentDialog class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize
+
+    "Created: / 11-05-2014 / 11:13:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'accessing'!
+
+answer: anAnswer forSelector: aSelector
+
+    methodAnswers 
+        at: aSelector 
+        put: anAnswer
+
+    "Created: / 11-05-2014 / 00:32:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+methodAnswer: aSelector   
+
+    ^ methodAnswers at: aSelector
+
+    "Created: / 11-05-2014 / 00:25:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'construction-adding'!
+
+addAbortAndOkButtons
+    "/ Nothing to do
+
+    "Created: / 15-09-2014 / 16:21:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView
+    "Add given component. Component is automatically stretched to occupy windows' width"
+
+    ^ CustomSilentDialog::NilComponent new
+
+    "Created: / 15-09-2014 / 18:48:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-10-2014 / 11:27:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+addComponent:aView labeled:labelString
+    "Add a label and some component side-by-side. Returns the component"
+
+    ^ CustomSilentDialog::NilComponent new
+
+    "Created: / 15-09-2014 / 15:45:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-10-2014 / 11:26:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'dialogs'!
+
+requestClassName:aString initialAnswer:anInitialAswer
+
+    ^ self methodAnswer: #requestClassName:initialAnswer:
+
+    "Created: / 11-05-2014 / 00:16:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'initialization'!
+
+initialize
+
+    methodAnswers := Dictionary new
+
+    "Created: / 11-05-2014 / 00:19:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'opening'!
+
+open
+    "/ Ignored
+
+    "Created: / 15-09-2014 / 16:23:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog methodsFor:'user interaction & notifications'!
+
+information: aString
+
+    ^ self
+
+    "Created: / 13-05-2014 / 22:33:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog::NilComponent class methodsFor:'documentation'!
+
+documentation
+"
+    Substitute for component in CustomDialog to hide any real UI.
+    This class just understand all method calls and returns self.
+"
+! !
+
+!CustomSilentDialog::NilComponent methodsFor:'queries'!
+
+doesNotUnderstand: aMessage
+    "Do nothing when a message arrives."
+
+    ^ self
+
+    "Created: / 14-10-2014 / 11:25:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSilentDialog class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleAccessMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,91 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomSimpleAccessMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSimpleAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSimpleAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Access Method(s) for selected instance variables'
+
+    "Modified: / 07-07-2014 / 22:20:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Access Method(s)'
+! !
+
+!CustomSimpleAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Creates access methods for given context"
+
+    self executeSubGeneratorOrRefactoringClasses:(Array 
+                  with:CustomSimpleGetterMethodsCodeGenerator
+                  with:CustomSimpleSetterMethodsCodeGenerator)
+          inContext:aCustomContext
+
+    "Modified: / 11-07-2014 / 21:16:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleAccessMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,109 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSimpleAccessMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSimpleAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSimpleAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomSimpleAccessMethodsCodeGenerator new
+! !
+
+!CustomSimpleAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_access_methods_generated_with_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: true;
+        generateCommentsForSetters: true.
+
+    expectedGetterSource := 'instanceVariable
+    "return the instance variable ''instanceVariable'' (automatically generated)"
+
+    ^ instanceVariable'.
+
+    expectedSetterSource := 'instanceVariable:something
+    "set the value of the instance variable ''instanceVariable'' (automatically generated)"
+
+    instanceVariable := something'.
+
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 08-07-2014 / 13:28:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-07-2014 / 16:02:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_access_methods_generated_without_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: false;
+        generateCommentsForSetters: false.
+
+    expectedGetterSource := 'instanceVariable
+    ^ instanceVariable'.
+
+    expectedSetterSource := 'instanceVariable:something
+    instanceVariable := something'.
+
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 08-07-2014 / 16:59:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleGetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,115 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomSimpleGetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSimpleGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSimpleGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+    ^ 'Getter methods for selected instance variables'
+
+    "Modified: / 11-05-2014 / 16:37:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Getters')
+
+    "Created: / 22-08-2014 / 18:56:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+    ^ 'Getter Method(s)'
+
+    "Modified (format): / 11-05-2014 / 16:29:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns simple getter method source code for given class and variable name"
+
+    | methodName comment |
+
+    methodName := self methodNameFor: aName.
+    comment := ''.
+
+    userPreferences generateCommentsForGetters ifTrue:[
+        | varType |
+
+        varType := self varTypeOf: aName class: aClass.
+        comment := '"return the %1 variable ''%2'' (automatically generated)"'.
+        comment := comment bindWith: varType with: aName.
+    ].  
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+        `"comment
+
+        ^ `variableName';
+        replace: '`@methodName' with: methodName asSymbol;
+        replace: '`variableName' with: aName asString;
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Created: / 19-05-2014 / 20:32:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-09-2014 / 22:35:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleGetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,103 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSimpleGetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSimpleGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSimpleGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomSimpleGetterMethodsCodeGenerator new
+
+    "Modified: / 29-05-2014 / 00:07:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_simple_getter_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: true.
+
+    expectedSource := 'instanceVariable
+    "return the instance variable ''instanceVariable'' (automatically generated)"
+
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 31-05-2014 / 20:06:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-06-2014 / 10:41:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_simple_getter_method_generated_without_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: false.
+
+    expectedSource := 'instanceVariable
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 31-05-2014 / 20:05:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-06-2014 / 10:41:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleSetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,119 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomSimpleSetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSimpleSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSimpleSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Setter methods for selected instance variables'
+
+    "Modified: / 04-07-2014 / 15:29:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Setters')
+
+    "Created: / 22-08-2014 / 18:55:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Setter Method(s)'
+
+    "Modified: / 04-07-2014 / 16:20:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns simple setter for given class and variable name."
+
+    | methodName comment argName |
+
+    methodName := self methodNameFor: aName.
+    argName := self argNameForMethodName: methodName.  
+    comment := ''.
+
+    userPreferences generateCommentsForSetters ifTrue:[
+        | varType |
+
+        varType := self varTypeOf: aName class: aClass. 
+        comment := '"set the value of the %1 variable ''%2'' (automatically generated)"'.
+        comment := comment bindWith: varType with: aName.
+    ].
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+            `"comment
+
+            `variableName := `argName';
+        replace: '`@methodName' with: (methodName, ': ', argName) asSymbol;
+        replace: '`argName' with: argName asString;
+        replace: '`variableName' with: aName asString;
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Modified: / 19-09-2014 / 22:36:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSimpleSetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,103 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSimpleSetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSimpleSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSimpleSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomSimpleSetterMethodsCodeGenerator new
+! !
+
+!CustomSimpleSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_simple_setter_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: true.
+
+    expectedSource := 'instanceVariable:something
+    "set the value of the instance variable ''instanceVariable'' (automatically generated)"
+
+    instanceVariable := something'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+    "Created: / 05-07-2014 / 13:29:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-07-2014 / 19:38:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_simple_setter_method_generated_without_comments
+    "test setter method"
+
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: false.
+
+    expectedSource := 'instanceVariable:something
+    instanceVariable := something'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+    "Created: / 05-07-2014 / 13:38:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-07-2014 / 19:38:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSimpleSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeFormatter.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,81 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomSourceCodeFormatter
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomSourceCodeFormatter class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Defines required methods for a source code formatter implementation used in this package.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!CustomSourceCodeFormatter class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!CustomSourceCodeFormatter methodsFor:'formatting'!
+
+formatParseTree: aParseTree
+    "Should return parse tree formatted as source code "
+
+    self subclassResponsibility
+
+    "Modified (comment): / 28-08-2014 / 22:13:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,231 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CodeGenerator subclass:#CustomSourceCodeGenerator
+	instanceVariableNames:'formatter commentPlaceholderMarker commentReplacements'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomSourceCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Extension for CodeGenerator to support work just with source code and with formatter.
+    Replacements definition are not stricly limited to just expressions, but also method call.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomSourceCodeGenerator methodsFor:'accessing'!
+
+commentPlaceholderMarker: aString
+    "
+    Sets prefix string which will mark comment replace 
+    in code replacements given by:
+    replace: '`comment' with: 'comment'
+    "
+
+    commentPlaceholderMarker := aString
+
+    "Created: / 19-09-2014 / 21:17:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter
+
+    ^ formatter
+
+    "Created: / 19-09-2014 / 22:24:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+formatter: aSourceCodeFormatter
+
+    formatter := aSourceCodeFormatter
+
+    "Created: / 19-09-2014 / 22:25:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+newSource
+    "
+    Returns formatted method source
+    code as string (with replacements and so on)
+    "
+
+    | parser method |  
+
+    source := self replaceCommentsInSource: source.
+    parser := RBParser new.
+    recordedReplacementsInSource := OrderedCollection new.
+    parser errorBlock:[ :str :pos | self error: ('Error: %1: %2' bindWith: pos with: str). ^ self ].
+
+    parser initializeParserWith: source type: #rewriteSavingCommentsOn:errorBlock:.
+    method := parser parseMethod: source.    
+
+    method source: nil.
+    method acceptVisitor: self.
+    self replaceInSourceCode.
+    method source: source.
+
+    ^ formatter formatParseTree: method.
+
+    "Created: / 19-09-2014 / 22:07:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replace: placeholder with: code
+
+    (placeholder startsWith: commentPlaceholderMarker) ifTrue: [
+        commentReplacements
+            at: placeholder 
+            put: code
+    ]
+    ifFalse: [
+        replacements 
+            at: placeholder
+            put: (self replacementFromCode: code)
+    ]
+
+    "Created: / 19-09-2014 / 21:18:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-09-2014 / 23:58:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGenerator methodsFor:'initialization'!
+
+initialize
+    "Invoked when a new instance is created."
+
+    super initialize.
+    commentPlaceholderMarker := '`"'.
+    commentReplacements := Dictionary new.
+
+    "Created: / 19-09-2014 / 21:42:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGenerator methodsFor:'private'!
+
+formatReplacement: replacement 
+    "Returns formatted source code replacement, but keep Symbol not formatted"
+
+    replacement isSymbol ifTrue: [ 
+        ^ replacement formattedCode
+    ].
+
+    ^ formatter formatParseTree: replacement
+
+    "Created: / 20-09-2014 / 10:01:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replaceCommentsInSource: aSourceCodeString
+    "
+    Returns source string with replaced occurences of comment
+    replaces given by:
+    replace: '`{double_quote_char}comment' with: '{double_quote_char}a comment{double_quote_char}'
+    where {double_quote_char} is "" (but not escaped like in this comment)
+    "
+
+    | sourceCode |
+
+    sourceCode := aSourceCodeString.
+
+    commentReplacements keysAndValuesDo: [ :placeholder :code | 
+        sourceCode := sourceCode copyReplaceString: placeholder withString: code       
+    ].
+
+    ^ sourceCode
+
+    "Created: / 19-09-2014 / 22:08:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replacePlaceholdersInSelectorPartsOf:aMessageNode 
+    aMessageNode selectorParts do:[:part | 
+        part isPatternVariable ifTrue:[
+            |replacement|
+
+            replacement := self replacementFor:part value.
+            "(replacement isSymbol or:[ replacement isVariable ]) ifFalse:[
+                self error:'Replacement for selector parts must be a single selector'
+            ]."
+            replacement isNil ifTrue: [ 
+                self error: 'None replacement for: ', part value asString.
+            ].
+            source notNil ifTrue:[
+                self 
+                      recordReplaceInSourceFrom:part start
+                      to:part stop
+                      by: (self formatReplacement: replacement).
+            ].
+            part value: (self formatReplacement: replacement).
+        ]
+    ]
+
+    "Created: / 19-09-2014 / 23:55:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 20-09-2014 / 10:14:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+replacementFromCode: aCode
+
+    ^ aCode isSymbol 
+        ifTrue:[aCode]
+        ifFalse:[
+            RBParser parseRewriteExpression: aCode onError: [ :str :pos |
+                RBParser parseRewriteMethod: aCode onError: [ :str :pos | 
+                    self error: 'Cannot parse: ', str, ' at pos: ', pos asString 
+                ]
+            ]
+        ]
+
+    "Created: / 19-09-2014 / 23:56:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,180 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomSourceCodeGeneratorTests
+	instanceVariableNames:'sourceCodeGenerator'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomSourceCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSourceCodeGeneratorTests methodsFor:'initialization & release'!
+
+setUp
+
+    sourceCodeGenerator := CustomSourceCodeGenerator new.
+    sourceCodeGenerator formatter: CustomNoneSourceCodeFormatter new.
+
+    "Modified: / 19-09-2014 / 23:42:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGeneratorTests methodsFor:'tests'!
+
+test_new_source_literal_replacement
+    |expectedSource actualSource|
+
+    actualSource := sourceCodeGenerator
+            replace:'`"comment1' with:'"comment1"';
+            replace:'`"comment2' with:'"other comment2"';
+            replace:'`#literal' with:'''some info''';
+            source:'selector
+    `"comment1
+
+    self information: `#literal.
+
+    `"comment2
+
+    ^ 55';
+            newSource.
+    expectedSource := 'selector
+    "comment1"
+
+    self information: ''some info''.
+
+    "other comment2"
+
+    ^ 55'.
+    self assert:expectedSource = actualSource.
+
+    "Created: / 19-09-2014 / 23:45:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_selector_as_symbol
+    | expectedSource actualSource |
+
+    actualSource := sourceCodeGenerator
+        source: '`@selector
+            self shouldImplement';
+        replace: '`@selector' with: 'aSelector: withParam' asSymbol;
+        newSource.    
+
+    expectedSource := 'aSelector: withParam
+            self shouldImplement'.
+
+    self assert: expectedSource = actualSource.
+
+    "Created: / 20-09-2014 / 09:36:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_selector_replacement
+    |expectedSource actualSource|
+
+    actualSource := sourceCodeGenerator
+            source:'`@selector
+            self shouldImplement';
+            replace:'`@selector' with:'aSelector';
+            newSource.
+    expectedSource := 'aSelector
+            self shouldImplement'.
+    self assert:expectedSource = actualSource.
+
+    "Created: / 19-09-2014 / 23:51:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_new_source_selector_with_param
+    | expectedSource actualSource |
+
+    actualSource := sourceCodeGenerator
+        source: '`@selector
+            self shouldImplement';
+        replace: '`@selector' with: 'aSelector: withParam';
+        newSource.    
+
+    expectedSource := 'aSelector: withParam
+            self shouldImplement'.
+
+    self assert: expectedSource = actualSource.
+
+    "Created: / 20-09-2014 / 09:39:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_replace_comments_in_source
+    | expectedSource actualSource |
+
+    actualSource := sourceCodeGenerator
+        replace: '`"comment1' with: '"comment1"'; 
+        replace: '`"comment2' with: '"other comment2"';
+        replaceCommentsInSource:'selector
+    `"comment1
+
+    self information: ''some info''.
+
+    `"comment2
+
+    ^ 55'.    
+
+    expectedSource := 'selector
+    "comment1"
+
+    self information: ''some info''.
+
+    "other comment2"
+
+    ^ 55'.
+    
+    self assert: expectedSource = actualSource.
+
+    "Created: / 19-09-2014 / 22:50:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeSelection.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,270 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomSourceCodeSelection
+	instanceVariableNames:'selectedInterval currentSourceCode selectedMethod selectedClass
+		selectedSelector'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomSourceCodeSelection class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Container class which holds actual source code from text editor (source code editor) 
+    with exact position of selected source code. Also keeps corresponding class, method and selector
+    to current source code.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomSourceCodeSelection methodsFor:'accessing'!
+
+currentSourceCode
+    "Returns the source code string. This is the code we actually
+    working on - for example modified method in code editor.
+    If such code is not directly known then is retrieved from selected method
+    or from selected class and selector."
+
+    currentSourceCode notNil ifTrue: [ 
+        ^ currentSourceCode
+    ].
+
+    self selectedMethod notNil ifTrue: [ 
+        ^ self selectedMethod source
+    ].
+
+    (selectedSelector notNil and: [selectedClass notNil]) ifTrue: [ 
+        ^ (selectedClass compiledMethodAt: selectedSelector asSymbol) source
+    ].
+
+    ^ nil
+
+    "Modified: / 28-10-2014 / 11:46:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+currentSourceCode: aSourceCode
+    "see ... currentSourceCode"
+
+    currentSourceCode := aSourceCode.
+
+    "Modified (comment): / 18-10-2014 / 12:03:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClass
+    "Returns the selected class which belongs to the selected source code."
+
+    ^ selectedClass
+
+    "Modified (comment): / 18-10-2014 / 12:27:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClass: aClass
+    "see ... selectedClass"
+
+    selectedClass := aClass.
+
+    "Modified (comment): / 18-10-2014 / 12:27:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedInterval
+    "Returns numeric interval to tell which fragment of the currentSourceCode is selected.
+    For example (2 to: 5) means that second to fifth character is selected."
+
+    ^ selectedInterval
+
+    "Modified (comment): / 18-10-2014 / 12:50:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedInterval: anInterval
+    "see ... selectedInterval"
+
+    selectedInterval := anInterval.
+
+    "Modified (comment): / 18-10-2014 / 12:51:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethod
+    "Returns the selected method which belongs to the selected source code."
+
+    ^ selectedMethod
+
+    "Modified (comment): / 18-10-2014 / 12:53:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethod: aMethod
+    "see ... selectedMethod"
+
+    selectedMethod := aMethod.
+
+    "Modified (comment): / 18-10-2014 / 12:53:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedSelector
+    "Returns the selected method selector which belongs to the selected source code.
+    If not known then returns selected method selector or source code."
+
+    | selector |
+
+    selectedSelector notNil ifTrue: [ 
+        ^ selectedSelector
+    ].
+
+    selector := nil.
+
+    self selectedMethod notNil ifTrue: [
+        selector := self selectedMethod selector
+    ].
+
+    selector isNil ifTrue: [
+        | source |
+
+        source := self currentSourceCode.
+        source notNil ifTrue: [
+            "In some cases the 'who' method from Method >> selector 
+            returns nil as selector so parse the selector from source"
+            selector := (Parser parseMethodSpecification: source) selector
+        ]
+    ].
+
+    ^ selector
+
+    "Modified (format): / 28-10-2014 / 12:20:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedSelector: aSelector
+    "see ... selectedSelector"
+
+    selectedSelector := aSelector.
+
+    "Modified (comment): / 18-10-2014 / 12:54:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedSourceCode
+    "Returns selected source code fragment as string from current source code
+    specified by selected interval.
+    For example when code is 'some_code' and interval is (2 to: 4) then 'ome' is returned."
+
+    | source interval |
+
+    source := self currentSourceCode.
+    source isNil ifTrue: [ ^ nil ].
+    source := source asString.
+
+    interval := self selectedInterval.
+
+    interval isNil ifTrue: [
+        "Return the whole source when none interval is specified"
+        ^ source
+    ].
+
+    interval isEmpty ifTrue: [
+        "Cannot retrieve any source when interval is empty, so return unknown source"
+        ^ nil
+    ].
+
+    (interval first between: 1 and: source size) ifFalse: [ 
+        self error: 'selectedInterval is not within currentSourceCode range'
+    ].
+
+    ^ source copyFrom: interval first to: (interval last min:source size)
+
+    "Created: / 24-08-2014 / 22:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 22:49:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelection methodsFor:'printing & storing'!
+
+printOn:aStream
+    "append a printed representation if the receiver to the argument, aStream"
+
+    super printOn:aStream.
+    aStream nextPutAll:' (selectedInterval: '.
+
+    self selectedInterval printOn:aStream.
+    aStream nextPutAll:'; currentSourceCode: '.
+
+    self currentSourceCode printOn:aStream.
+    aStream nextPutAll:'; selectedMethod: '.
+
+    self selectedMethod printOn:aStream.
+    aStream nextPutAll:'; selectedClass: '.
+
+    self selectedClass printOn:aStream.
+    aStream nextPutAll:'; selectedSelector: '.
+
+    self selectedSelector printOn:aStream.
+    aStream nextPutAll:')'.
+
+    "Modified: / 28-10-2014 / 10:25:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelection methodsFor:'queries'!
+
+isWholeMethodSelected
+    "Returns true if complete method source code is selected
+    othervise returns false"
+
+    self selectedMethod isNil ifTrue: [ 
+        ^ false
+    ].
+
+    ^ (self currentSourceCode) = (self selectedSourceCode)
+
+    "Created: / 07-12-2014 / 18:48:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelection class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSourceCodeSelectionTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,306 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomSourceCodeSelectionTests
+	instanceVariableNames:'codeSelection'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomSourceCodeSelectionTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSourceCodeSelectionTests methodsFor:'initialization & release'!
+
+setUp
+
+    codeSelection := CustomSourceCodeSelection new.
+
+    "Created: / 24-08-2014 / 22:51:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelectionTests methodsFor:'tests'!
+
+test_current_source_code_class_and_selector_filled
+
+    codeSelection 
+        selectedClass: self class;
+        selectedSelector: #setUp.    
+    
+    self assert: (codeSelection currentSourceCode startsWith: 'setUp').
+
+    "Created: / 24-08-2014 / 22:56:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_current_source_code_filled
+
+    codeSelection currentSourceCode: 'src'.
+    
+    self assert: codeSelection currentSourceCode = 'src'.
+
+    "Created: / 24-08-2014 / 22:54:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_current_source_code_method_filled
+
+    codeSelection selectedMethod: (self class compiledMethodAt: #setUp).    
+    
+    self assert: (codeSelection currentSourceCode startsWith: 'setUp').
+
+    "Created: / 24-08-2014 / 22:55:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_current_source_code_not_filled
+    
+    self assert: codeSelection currentSourceCode isNil.
+
+    "Created: / 24-08-2014 / 22:57:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_all_empty
+    
+    self deny: codeSelection isWholeMethodSelected
+
+    "Created: / 07-12-2014 / 18:51:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_complete_selection
+    | method |
+
+    method := self class compiledMethodAt: #test_is_whole_method_selected_complete_selection.  
+
+    codeSelection
+        selectedInterval: (1 to: method source size);
+        selectedMethod: method.    
+    
+    self assert: codeSelection isWholeMethodSelected
+
+    "Created: / 07-12-2014 / 19:11:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_empty_method
+
+    codeSelection
+        selectedInterval: (3 to: 6);
+        currentSourceCode: 'some code'.    
+    
+    self deny: codeSelection isWholeMethodSelected
+
+    "Created: / 07-12-2014 / 19:09:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_is_whole_method_selected_empty_selection
+
+    codeSelection selectedMethod: (self class compiledMethodAt: #test_is_whole_method_selected_empty_selection).    
+    
+    self assert: codeSelection isWholeMethodSelected
+
+    "Modified: / 07-12-2014 / 18:53:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_print_on_all_filled
+    | expectedString actualString stream method |
+
+    method := (self class compiledMethodAt: #test_print_on_all_filled).
+
+    expectedString := 'a SmallSense::CustomSourceCodeSelection (selectedInterval: 2 to:5; ',
+        'currentSourceCode: test_print_on_all_filled ^ 265; ',
+        'selectedMethod: ', method asString, '; ',
+        'selectedClass: SmallSense::CustomSourceCodeSelectionTests; selectedSelector: test_print_on_all_filled)'.
+
+    stream := WriteStream on:(String new).
+
+    codeSelection
+        selectedClass: self class;
+        selectedMethod: method;
+        selectedInterval: (2 to: 5);
+        selectedSelector: #test_print_on_all_filled;
+        currentSourceCode: 'test_print_on_all_filled ^ 265'.
+
+    codeSelection printOn:stream.    
+
+    actualString := stream contents.
+    
+    self assert: expectedString = actualString.
+
+    "Modified: / 25-01-2015 / 14:36:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 21:07:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_selected_selector_from_method
+    | expectedSelector actualSelector |
+
+    expectedSelector := #test_selected_selector_from_method.
+    codeSelection selectedMethod: (self class compiledMethodAt: #test_selected_selector_from_method).
+
+    actualSelector := codeSelection selectedSelector.
+
+    self assert: expectedSelector = actualSelector.
+
+    "Created: / 28-10-2014 / 09:31:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_selector_from_source
+    | expectedSelector actualSelector |
+
+    expectedSelector := #test_selector_01.
+    codeSelection currentSourceCode: 'test_selector_01 ^ 101'.
+
+    actualSelector := codeSelection selectedSelector.
+
+    self assert: expectedSelector = actualSelector.
+
+    "Created: / 28-10-2014 / 10:52:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_selector_known
+    | expectedSelector actualSelector |
+
+    expectedSelector := #selector_01.
+    codeSelection selectedSelector: expectedSelector.
+
+    actualSelector := codeSelection selectedSelector.
+
+    self assert: expectedSelector = actualSelector.
+
+    "Created: / 28-10-2014 / 09:30:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_selector_unknown
+    | expectedSelector actualSelector |
+
+    expectedSelector := nil.
+    actualSelector := codeSelection selectedSelector.
+
+    self assert: expectedSelector = actualSelector.
+
+    "Created: / 28-10-2014 / 09:29:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_nil_when_unknown
+    
+    self assert: codeSelection selectedSourceCode isNil
+
+    "Modified: / 05-11-2014 / 22:51:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_part_code
+
+    codeSelection
+        currentSourceCode: 'selector ^ self otherSelector.';
+        selectedInterval: (12 to: 15).
+
+    self assert: codeSelection selectedSourceCode = 'self'.
+
+    "Created: / 24-08-2014 / 23:06:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_whole_code
+
+    codeSelection
+        currentSourceCode: 'selector ^ self otherSelector.';
+        selectedInterval: (1 to: 30).
+
+    self assert: codeSelection selectedSourceCode = 'selector ^ self otherSelector.'.
+
+    "Created: / 24-08-2014 / 22:58:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_code_with_exceeding_interval
+
+    codeSelection
+        currentSourceCode: 'selector ^ self otherSelector.';
+        selectedInterval: (1 to: 9999999).
+
+    self assert: codeSelection selectedSourceCode = 'selector ^ self otherSelector.'.
+
+    "Created: / 18-10-2014 / 13:13:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_interval_empty
+
+    codeSelection
+        currentSourceCode: 'selector ^ self otherSelector.';
+        selectedInterval: (1 to: 0).
+
+    self assert: codeSelection selectedSourceCode isNil.
+
+    "Created: / 14-10-2014 / 10:22:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_interval_wrong
+
+    codeSelection
+        currentSourceCode: 'selector ^ self otherSelector.';
+        selectedInterval: (9999 to: 99999).
+
+    self should: [
+        codeSelection selectedSourceCode
+    ]  raise: Error
+
+    "Created: / 18-10-2014 / 13:06:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_source_unknown
+    | expectedSource |
+
+    expectedSource := 'selector ^ self otherSelector.'.
+
+    codeSelection
+        currentSourceCode: expectedSource.
+
+    self assert: expectedSource = (codeSelection selectedSourceCode).
+
+    "Created: / 14-10-2014 / 10:19:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 28-10-2014 / 09:13:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSourceCodeSelectionTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubContext.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,201 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomContext subclass:#CustomSubContext
+	instanceVariableNames:'selectedClasses selectedClassCategories selectedProtocols
+		selectedMethods selectedPackages selectedVariables selectedCodes'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom'
+!
+
+!CustomSubContext class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSubContext methodsFor:'accessing'!
+
+selectedClassCategories: classCategories
+    "Sets the list of class categories" 
+
+    selectedClassCategories := classCategories.
+
+    "Modified (comment): / 29-11-2014 / 18:32:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses: classes
+    "Sets the list of classes"
+
+    selectedClasses := classes
+
+    "Created: / 26-04-2014 / 16:05:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-11-2014 / 19:26:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 20:23:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes: something
+    "Sets the list of code selections - instances of CustomSourceCodeSelection" 
+
+    selectedCodes := something.
+
+    "Created: / 18-08-2014 / 23:53:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 29-11-2014 / 18:33:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods: methods
+    "Sets the list of methods"
+
+    selectedMethods := methods.
+
+    "Modified: / 25-11-2014 / 20:27:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages: packages
+    "Sets the list of packages" 
+
+    selectedPackages := packages.
+
+    "Modified (comment): / 29-11-2014 / 18:31:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols: protocols
+    "Sets the list of method protocols (i.e. categories)" 
+
+    selectedProtocols := protocols.
+
+    "Modified (comment): / 29-11-2014 / 18:34:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables: variables
+    "Sets the list of class variable names" 
+
+    selectedVariables := variables.
+
+    "Modified (comment): / 29-11-2014 / 18:36:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContext methodsFor:'accessing-selection'!
+
+selectedClassCategories
+
+    ^ selectedClassCategories
+
+    "Modified: / 05-05-2014 / 20:31:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedClasses
+    "Returns the list of classes"
+
+    "classes is supposed to be a collection of RBClass/RBMetaclass. However, if real classes
+     are passed, they are converted to RBClasses here for your convenience"
+
+    ^ selectedClasses ? #() collect: [ :class | 
+        class isBehavior
+            ifTrue:[ self asRBClass: class ] 
+            ifFalse:[ class ]
+    ]
+
+    "Created: / 19-12-2013 / 12:24:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 25-11-2014 / 20:24:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedCodes
+
+    ^ selectedCodes
+
+    "Created: / 18-08-2014 / 23:52:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedMethods
+    "Returns the list of methods"
+
+    "methods is supposed to be a collection of RBMethod. However, if real methods (Method)
+     are passed, they are converted to RBMethod here for your convenience"
+
+    ^ selectedMethods ? #() collect: [ :method | 
+        method isMethod 
+            ifTrue:[ self asRBMethod: method ] 
+            ifFalse:[ method ]  
+    ]
+
+    "Modified (comment): / 25-11-2014 / 20:26:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedPackages
+
+    ^ selectedPackages
+
+    "Modified: / 05-05-2014 / 20:32:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedProtocols
+    ^ selectedProtocols
+
+    "Modified: / 05-05-2014 / 20:31:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+selectedVariables
+
+    ^ selectedVariables
+
+    "Modified: / 05-05-2014 / 20:32:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContext methodsFor:'initialization'!
+
+initialize
+
+    super initialize.
+    selectedClasses := OrderedCollection new.
+
+    "Created: / 19-12-2013 / 12:37:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-11-2014 / 10:19:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContext class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubContextTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,138 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomSubContextTests
+	instanceVariableNames:'model context'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Tests'
+!
+
+!CustomSubContextTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSubContextTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    model := CustomNamespace new.
+    context := CustomSubContext new
+        model: model;
+        yourself
+
+    "Modified: / 19-11-2014 / 19:59:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubContextTests methodsFor:'tests'!
+
+test_selected_classes_as_rb_class
+
+    |expectedClasses actualClasses modelClass|
+
+    modelClass := model classNamed: self class name.
+    expectedClasses := Array with: modelClass.
+
+    context selectedClasses: (Array with: self class).
+    actualClasses := context selectedClasses.
+
+    self assert: expectedClasses = actualClasses
+
+    "Created: / 25-11-2014 / 20:31:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_classes_existing_rb_class
+
+    |expectedClasses actualClasses modelClass|
+
+    modelClass := model classNamed: self class name.
+    expectedClasses := Array with: modelClass.
+
+    context selectedClasses: (Array with: modelClass).
+    actualClasses := context selectedClasses.
+
+    self assert: expectedClasses = actualClasses
+
+    "Created: / 25-11-2014 / 20:37:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_methods_as_rb_method
+
+    |expectedMethods realMethod actualMethods modelClass modelMethod|
+
+    modelClass := model classNamed: self class name.
+    modelMethod := modelClass compiledMethodAt: #test_selected_methods_as_rb_method.
+    expectedMethods := Array with: modelMethod.
+
+    realMethod := self class compiledMethodAt: #test_selected_methods_as_rb_method.
+    context selectedMethods: (Array with: realMethod).
+    actualMethods := context selectedMethods.
+
+    "Cannot test collection equality, because each contains different RBMethod instance
+    self assert: expectedMethods = actualMethods"
+    self assert: (expectedMethods size) = (actualMethods size).
+    self assert: (expectedMethods first selector) = (actualMethods first selector).
+    self assert: (expectedMethods first isKindOf: RBMethod).    
+    self deny: expectedMethods first isMethod
+
+    "Modified: / 19-11-2014 / 20:29:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 25-11-2014 / 20:30:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_selected_methods_existing_rb_method
+
+    |expectedMethods actualMethods modelClass modelMethod|
+
+    modelClass := model classNamed: self class name.
+    modelMethod := modelClass compiledMethodAt: #test_selected_methods_as_rb_method.
+    expectedMethods := Array with: modelMethod.
+
+    context selectedMethods: (Array with: modelMethod).
+    actualMethods := context selectedMethods.
+
+    self assert: expectedMethods = actualMethods
+
+    "Created: / 19-11-2014 / 20:30:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubclassResponsibilityCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,205 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomSubclassResponsibilityCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Generates method stubs marked by: self subclassResponsibility'
+
+    "Modified: / 08-04-2014 / 21:40:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Subclass responsibility methods'
+
+    "Modified: / 08-04-2014 / 21:38:02 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'queries'!
+
+availableInContext: aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise. 
+
+     Called by the UI to figure out what generators / refactorings 
+     are available at given point. See class CustomContext for details."
+
+    ^ aCustomContext selectedClasses notEmptyOrNil
+
+!
+
+availableInPerspective:aCustomPerspective 
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    ^ aCustomPerspective isClassPerspective
+
+! !
+
+!CustomSubclassResponsibilityCodeGenerator methodsFor:'code generation'!
+
+createSubclassResponsibilityForClass: anRBClass
+
+    | missingRequiredSelectors classQuery |
+
+    classQuery := CustomClassQuery new.
+    self determineIsClassAbstract: anRBClass.
+    missingRequiredSelectors := self missingRequiredProtocolFor: anRBClass.
+
+    missingRequiredSelectors isCollection ifTrue: [
+        missingRequiredSelectors do: [ :selector |
+            | superclassMethod |
+
+            superclassMethod := (classQuery methodForSuperclassSelector: selector class: anRBClass).
+
+            model createMethod
+                class: anRBClass;
+                protocol: superclassMethod category;
+                source: ('`@selector
+
+                    self shouldImplement');
+                replace: '`@selector' with: superclassMethod methodDefinitionTemplate asSymbol;
+                compile. 
+        ]
+    ]
+
+    "Created: / 09-04-2014 / 20:16:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-12-2014 / 23:19:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 06:41:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator methodsFor:'executing'!
+
+buildInContext:aCustomContext
+
+    aCustomContext selectedClasses do: [ :class |
+        self
+            createSubclassResponsibilityForClass: class theNonMetaclass;
+            createSubclassResponsibilityForClass: class theMetaclass.
+    ]
+
+    "Created: / 08-04-2014 / 21:33:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 13-05-2014 / 22:04:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator methodsFor:'private'!
+
+determineIsClassAbstract: aClass
+    "For model class (RBClass, RBMetaclass) determines if the class is abstract or not.
+    Original RBAbstractClass >> isAbstract implementation returns mostly wrong guess,
+    especially for newly created classes."
+
+    aClass isBehavior ifTrue: [
+        "Nothing to do a for real class"
+        ^ self
+    ].
+
+    aClass isDefined ifTrue: [ 
+        aClass isAbstract: aClass realClass isAbstract
+    ] ifFalse: [ 
+        "For newly created class lets assume thats not abstract"
+        aClass isAbstract: false  
+    ].
+
+    "Created: / 14-12-2014 / 23:19:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+missingRequiredProtocolFor:aClass
+    "return the missing required protocol; 
+     that is the set of selectors which send #subclassResponsibility in a superclass and 
+     have no implementation in aClass or in any class between aClass and that superclass"
+
+    |requiredSelectors implementedSelectors|
+
+    aClass isAbstract ifTrue:[
+        "abstract classes are not responsible for methods to be defined in subclasses"    
+        ^ #().
+    ].
+
+    requiredSelectors := IdentitySet new.
+    implementedSelectors := IdentitySet withAll:(aClass methodDictionary keys).
+
+    aClass allSuperclassesDo:[:eachSuperClass |
+        eachSuperClass methodDictionary keysAndValuesDo:[:eachSelector :eachMethod |
+            (eachMethod sendsAnySelector:#( #subclassResponsibility #subclassResponsibility: )) ifTrue:[
+                (implementedSelectors includes:eachSelector) ifFalse:[
+                    requiredSelectors add:eachSelector.
+                ]
+            ] ifFalse:[
+                (requiredSelectors includes:eachSelector) ifFalse:[
+                    implementedSelectors add:eachSelector.
+                ].
+            ].
+        ]
+    ].
+    ^ requiredSelectors
+
+    "Created: / 11-05-2015 / 06:41:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomSubclassResponsibilityCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,212 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomSubclassResponsibilityCodeGeneratorTests
+	instanceVariableNames:'mockSuperClass mockClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomSubclassResponsibilityCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+
+    ^ CustomSubclassResponsibilityCodeGenerator new
+
+    "Created: / 29-08-2014 / 21:41:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests methodsFor:'initialization & release'!
+
+setUp
+
+    super setUp.
+    mockSuperClass := model createClassImmediate: 'MockSuperClassForTestCase' superClassName: 'Object'.
+    mockClass := model createClassImmediate: 'MockClassForTestCase' superClassName: (mockSuperClass new className).
+
+    "Created: / 14-04-2014 / 17:16:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 21:39:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests methodsFor:'tests'!
+
+test_determine_is_class_abstract_model_class
+    | expectedIsAbstract actualIsAbstract class |
+
+    class := model createClass
+        name: #DummyClass01;
+        compile;
+        yourself.
+
+    expectedIsAbstract := false.
+    generatorOrRefactoring determineIsClassAbstract: class.
+    actualIsAbstract := class isAbstract.
+    
+    self assert: expectedIsAbstract = actualIsAbstract
+
+    "Created: / 14-12-2014 / 23:46:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_determine_is_class_abstract_real_abstract_class_wrapped_with_model_class
+    | expectedIsAbstract actualIsAbstract class realClass |
+
+    realClass := model createClassImmediate: #DummyClass01.
+    model createMethodImmediate: realClass class source: 'isAbstract ^ true'.
+
+    class := model classNamed: #DummyClass01.
+    expectedIsAbstract := true.
+    generatorOrRefactoring determineIsClassAbstract: class.
+    actualIsAbstract := class isAbstract.
+    
+    self assert: expectedIsAbstract = actualIsAbstract
+
+    "Created: / 14-12-2014 / 23:45:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_determine_is_class_abstract_real_class
+    | expectedIsAbstract actualIsAbstract |
+
+    expectedIsAbstract := false.
+    generatorOrRefactoring determineIsClassAbstract: self class.
+    actualIsAbstract := self class isAbstract.
+    
+    self assert: expectedIsAbstract = actualIsAbstract
+
+    "Modified: / 14-12-2014 / 23:35:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_determine_is_class_abstract_real_class_wrapped_with_model_class
+    | expectedIsAbstract actualIsAbstract class |
+
+    class := model classNamed: self class name.
+    expectedIsAbstract := false.
+    generatorOrRefactoring determineIsClassAbstract: class.
+    actualIsAbstract := class isAbstract.
+    
+    self assert: expectedIsAbstract = actualIsAbstract
+
+    "Created: / 14-12-2014 / 23:38:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_none_subclass_responsibility
+
+    context selectedClasses: (Array with: mockClass).
+
+    model createMethodImmediate: mockSuperClass protocol: 'instance-protocol' source: 'instanceMethod: aParam
+    ^ self'.
+
+    self assert: (mockClass includesSelector: #instanceMethod:) not. 
+    self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+    generatorOrRefactoring executeInContext: context.
+
+    self assert: (mockClass includesSelector: #instanceMethod:) not.
+    self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+    "Created: / 13-05-2014 / 21:49:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 20:12:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_subclass_responsibility_class_method
+    | expectedSource |
+
+    context selectedClasses: (Array with: mockClass).
+
+    model createMethodImmediate: mockSuperClass class protocol: 'class-protocol' source: 'classMethod: aParam
+    self subclassResponsibility'.
+
+    self assert: (mockClass includesSelector: #classMethod:) not.
+    self assert: (mockClass class includesSelector: #classMethod:) not.
+
+    generatorOrRefactoring executeInContext: context.
+
+    self assert: (mockClass includesSelector: #classMethod:) not.
+    self assert: (mockClass class includesSelector: #classMethod:). 
+
+    expectedSource := 'classMethod:aParam
+    self shouldImplement'.
+
+    self assertMethodSource: expectedSource atSelector: #classMethod: forClass: mockClass class.
+
+    "Created: / 15-04-2014 / 22:05:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 20:12:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_subclass_responsibility_instance_method
+
+    |expectedSource|
+
+    context selectedClasses: (Array with: mockClass).
+
+    model createMethodImmediate: mockSuperClass protocol: 'instance-protocol' source: 'instanceMethod: aParam
+    self subclassResponsibility'.
+
+    self assert: (mockClass includesSelector: #instanceMethod:) not. 
+    self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+    generatorOrRefactoring executeInContext: context.
+
+    self assert: (mockClass includesSelector: #instanceMethod:).
+    self assert: (mockClass class includesSelector: #instanceMethod:) not.
+
+    expectedSource := 'instanceMethod:aParam
+    self shouldImplement'.
+
+    self assertMethodSource: expectedSource atSelector: #instanceMethod: forClass: mockClass.
+
+    "Created: / 14-04-2014 / 18:10:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 20:12:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomSubclassResponsibilityCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,343 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseCodeGenerator
+	instanceVariableNames:'testClassName testSuperName testClassCategory generateSetUp
+		generateTearDown samePackageAsTestedClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    ^ 'Creates a new test case'
+
+    "Created: / 16-09-2014 / 11:32:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Testing')
+
+    "Created: / 05-08-2014 / 14:52:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'New Test Case'
+
+    "Created: / 16-09-2014 / 11:23:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext 
+    | classes |
+
+    classes := aCustomContext selectedClasses.
+    ^ classes isEmptyOrNil or:[ classes noneSatisfy: [:cls | cls inheritsFrom: Smalltalk::TestCase ] ].
+
+    "Modified: / 12-06-2015 / 20:45:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective 
+    ^aCustomPerspective isClassPerspective
+! !
+
+!CustomTestCaseCodeGenerator methodsFor:'accessing'!
+
+generateSetUp
+    ^ generateSetUp
+!
+
+generateSetUp:aBoolean
+    generateSetUp := aBoolean.
+!
+
+generateTearDown
+    ^ generateTearDown
+!
+
+generateTearDown:aBoolean
+    generateTearDown := aBoolean.
+!
+
+samePackageAsTestedClass
+    "Returns true when we should assign TestCase class 
+    to the same package as tested class."
+
+    ^ samePackageAsTestedClass
+
+    "Created: / 15-11-2014 / 11:54:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+samePackageAsTestedClass: aBoolean
+    "see samePackageAsTestedClass"
+
+    samePackageAsTestedClass := aBoolean
+
+    "Created: / 15-11-2014 / 11:56:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+testClassCategory
+    ^ testClassCategory
+!
+
+testClassCategory:aString
+    testClassCategory := aString.
+!
+
+testClassName
+    ^ testClassName
+!
+
+testClassName:aString
+    testClassName := aString.
+!
+
+testSuperName
+    ^ testSuperName
+!
+
+testSuperName:aString
+    testSuperName := aString.
+! !
+
+!CustomTestCaseCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultGenerateSetUp
+    "raise an error: this method should be implemented (TODO)"
+
+    ^ false
+
+    "Created: / 16-09-2014 / 10:27:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+defaultGenerateTearDown
+    "raise an error: this method should be implemented (TODO)"
+
+    ^ false
+
+    "Created: / 16-09-2014 / 10:27:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+defaultSamePackageAsTestedClass
+    "default value for samePackageAsTestedClass"
+
+    ^ true
+
+    "Created: / 15-11-2014 / 12:21:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+defaultSetUpCodeGeneratorClass
+    ^ CustomTestCaseSetUpCodeGenerator
+!
+
+defaultTearDownCodeGeneratorClass
+    ^ CustomTestCaseTearDownCodeGenerator
+!
+
+defaultTestSuperName
+    ^ 'TestCase'
+! !
+
+!CustomTestCaseCodeGenerator methodsFor:'executing - private'!
+
+buildInContext:aCustomContext 
+    | classes |
+
+    classes := aCustomContext selectedClasses.
+    classes notEmptyOrNil ifTrue: [ 
+        classes do: [:cls | 
+            | name | 
+
+            name := cls theNonMetaClass name , 'Tests'.
+            self generateTestCaseNamed:name forClassUnderTest: cls theNonMetaclass
+        ]
+    ] ifFalse:[ 
+        self generateTestCaseNamed:testClassName forClassUnderTest: nil .  
+    ].
+
+    "Modified: / 16-09-2014 / 10:30:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 23:49:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext 
+    | classes |
+
+    classes := aCustomContext selectedClasses.
+    testSuperName := self defaultTestSuperName.
+    classes isEmptyOrNil ifTrue:[
+        testClassName := 'NewTestCase'.
+        testClassCategory := 'Some Tests'
+    ] ifFalse:[
+        classes size == 1 ifTrue:[
+            testClassName := classes anElement theNonMetaclass name , 'Tests'.
+            testClassCategory := classes anElement theNonMetaclass category , '-Tests'.
+        ] ifFalse:[
+            testClassCategory := 'Some Tests'.
+        ].
+    ].
+    generateSetUp := self defaultGenerateSetUp.
+    generateTearDown := self defaultGenerateTearDown.
+    samePackageAsTestedClass := self defaultSamePackageAsTestedClass.
+    
+    "/ Now open the dialog...
+
+    classes size <= 1 ifTrue: [
+        dialog 
+            addClassNameEntryOn:((AspectAdaptor forAspect:#testClassName) 
+                    subject:self)
+            labeled:'Class'
+            validateBy:nil.
+    ].
+
+    dialog 
+        addClassNameEntryOn:((AspectAdaptor forAspect:#testSuperName) 
+                subject:self)
+        labeled:'Superclass'
+        validateBy:nil.
+    dialog 
+        addClassCategoryEntryOn:((AspectAdaptor forAspect:#testClassCategory) 
+                subject:self)
+        labeled:'Category'
+        validateBy:nil.
+    dialog addSeparator.
+    dialog 
+        addCheckBoxOn:((AspectAdaptor forAspect:#generateSetUp) subject:self)
+        labeled:'Generate #setUp'.
+    dialog 
+        addCheckBoxOn:((AspectAdaptor forAspect:#generateTearDown) subject:self)
+        labeled:'Generate #tearDown'.
+    dialog 
+        addCheckBoxOn:((AspectAdaptor forAspect:#samePackageAsTestedClass) subject:self)
+        labeled:'Same package as tested class'.   
+    dialog addButtons.
+    dialog open.
+
+    "Created: / 16-09-2014 / 09:39:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 16-09-2014 / 11:27:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:03:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generateTestCaseCodeFor:testCase forClassUnderTest:anObject 
+    self 
+        generateTestCaseSetUpCodeFor: testCase;
+        generateTestCaseTearDownCodeFor: testCase.
+
+    "Modified: / 16-09-2014 / 11:16:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+generateTestCaseNamed:testCaseClassName forClassUnderTest:classUnderTest 
+    | testCase |
+
+    (testCase := model createClass)
+        superclassName:testSuperName;
+        name:testClassName asSymbol;
+        category:testClassCategory.
+
+    self samePackageAsTestedClass ifTrue: [ 
+        testCase package: classUnderTest package
+    ].
+
+    testCase compile.
+
+    self generateTestCaseCodeFor:testCase forClassUnderTest:classUnderTest
+
+    "Created: / 16-09-2014 / 10:28:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-11-2014 / 15:32:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generateTestCaseSetUpCodeFor: testCase   
+    generateSetUp ifTrue: [
+        | subcontext |
+
+        subcontext := CustomSubContext new.
+        subcontext selectedClasses: (Array with: testCase).
+        (self defaultSetUpCodeGeneratorClass subGeneratorOrRefactoringOf: self)
+            samePackageAsTestedClass: self samePackageAsTestedClass;  
+            executeInContext: subcontext.
+    ].
+
+    "Created: / 16-09-2014 / 11:15:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-10-2014 / 23:52:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-01-2015 / 23:30:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+generateTestCaseTearDownCodeFor: testCase 
+    generateTearDown ifTrue: [
+        | subcontext |
+
+        subcontext := CustomSubContext new.
+        subcontext selectedClasses: (Array with: testCase).
+        (self defaultTearDownCodeGeneratorClass subGeneratorOrRefactoringOf: self) 
+            samePackageAsTestedClass: self samePackageAsTestedClass;  
+            executeInContext:subcontext.
+    ].
+
+    "Created: / 16-09-2014 / 11:15:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 01-10-2014 / 23:52:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-01-2015 / 22:14:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,236 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^CustomTestCaseCodeGenerator new
+! !
+
+!CustomTestCaseCodeGeneratorTests methodsFor:'tests'!
+
+test_available_in_context_classes_all_test_case_subclass
+
+    context selectedClasses: {self class}.  
+    
+    self deny: (generatorOrRefactoring class availableInContext: context)
+
+    "Created: / 31-01-2015 / 22:05:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_classes_none_test_case_subclass
+
+    context selectedClasses: {Object}.  
+    
+    self assert: (generatorOrRefactoring class availableInContext: context)
+
+    "Created: / 31-01-2015 / 22:03:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_classes_one_test_case_subclass
+
+    context selectedClasses: {Object. self class}.  
+    
+    self deny: (generatorOrRefactoring class availableInContext: context)
+
+    "Created: / 31-01-2015 / 22:04:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty_classes
+
+    context selectedClasses: #().  
+    
+    self assert: (generatorOrRefactoring class availableInContext: context)
+
+    "Modified: / 31-01-2015 / 22:01:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_unknown_classes
+
+    context selectedClasses: nil.  
+    
+    self assert: (generatorOrRefactoring class availableInContext: context)
+
+    "Created: / 31-01-2015 / 22:01:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+    
+    self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective)
+
+    "Modified: / 31-01-2015 / 22:07:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_all_checked
+    | class testClass setUpSource tearDownSource |
+
+    class := self classWithInstanceVariable
+        category: 'Some-Category';
+        package: #some_package_01;
+        yourself.
+
+    self assertClassNotExists: class name.
+
+    context selectedClasses: {class}.
+
+    generatorOrRefactoring
+        configureInContext: context;
+        samePackageAsTestedClass: true;
+        generateSetUp: true;
+        generateTearDown: true;
+        testClassCategory: 'Some-Tests';
+        testClassName: #DummyClassTests;
+        testSuperName: #TestCase;
+        executeInContext: context.
+
+    testClass := Smalltalk at: #DummyClassTests.
+
+    self assert: (testClass package) = #some_package_01.
+    self assert: (testClass superclass name) = #TestCase.
+    self assert: (testClass category) = 'Some-Tests'.
+
+    setUpSource := 'setUp
+    super setUp.
+
+    "Add your own code here..."'.
+    self assertMethodSource: setUpSource atSelector: #setUp forClass: testClass. 
+
+    tearDownSource := 'tearDown
+    "Add your own code here..."
+
+    super tearDown.'
+.
+    self assertMethodSource: tearDownSource atSelector: #tearDown forClass: testClass
+
+    "Created: / 31-01-2015 / 23:02:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_for_metaclass
+    | class |
+
+    class := self classWithInstanceVariable
+        category: 'Some-Category';
+        yourself.
+
+    self assertClassNotExists: class name.
+
+    context selectedClasses: (Array with: class theMetaclass ).
+    generatorOrRefactoring
+        configureInContext: context;
+        executeInContext: context.
+
+    self assertClassExists: class name
+
+    "Created: / 14-10-2014 / 10:42:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 05-11-2014 / 22:37:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_with_package
+    | class testClass |
+
+    class := self classWithInstanceVariable
+        category: 'Some-Category';
+        package: #some_package_01;
+        yourself.
+
+    self assertClassNotExists: class name.
+
+    context selectedClasses: (Array with: class theMetaclass ).
+
+    generatorOrRefactoring
+        configureInContext: context;
+        executeInContext: context.
+
+    self assert: generatorOrRefactoring samePackageAsTestedClass.  
+
+    testClass := Smalltalk at: generatorOrRefactoring testClassName asSymbol.
+
+    self assertClassExists: class name.
+    self assert: (testClass package) = #some_package_01.
+
+    "Created: / 15-11-2014 / 15:21:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_class_generated_without_package
+    | class testClass |
+
+    class := self classWithInstanceVariable
+        category: 'Some-Category';
+        package: #some_package_01;
+        yourself.
+
+    self assertClassNotExists: class name.
+
+    context selectedClasses: (Array with: class theMetaclass ).
+
+    generatorOrRefactoring
+        configureInContext: context;
+        samePackageAsTestedClass: false;
+        executeInContext: context.
+
+    testClass := Smalltalk at: generatorOrRefactoring testClassName asSymbol.
+
+    self assertClassExists: class name.
+    self deny: (testClass package) = #some_package_01.
+
+    "Created: / 15-11-2014 / 15:37:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseHelper.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,82 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Object subclass:#CustomTestCaseHelper
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Helpers'
+!
+
+!CustomTestCaseHelper class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    Helper class with utility methods used in TestCase generators/refactoring.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz> 
+"
+! !
+
+!CustomTestCaseHelper methodsFor:'helpers'!
+
+testCategory: aCategory
+    "Returns category based on given category in which should be TestCase located
+    e.g. from Category creates Category-Tests"
+    | suffix |
+
+    suffix := '-Tests'.
+
+    (aCategory asString endsWith: suffix) ifTrue: [
+        ^ aCategory    
+    ].
+
+    ^ aCategory asString, suffix.
+
+    "Created: / 30-08-2014 / 20:01:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 08-11-2014 / 21:09:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseHelperTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,90 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+Smalltalk::TestCase subclass:#CustomTestCaseHelperTests
+	instanceVariableNames:'testCaseHelper'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Helpers-Tests'
+!
+
+!CustomTestCaseHelperTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseHelperTests methodsFor:'initialization & release'!
+
+setUp
+    super setUp.
+
+    testCaseHelper := CustomTestCaseHelper new
+
+    "Modified: / 08-11-2014 / 21:11:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseHelperTests methodsFor:'tests'!
+
+test_test_category_ending_with_tests
+    | expectedCategory actualCategory |
+
+    expectedCategory := 'Some-Category-Tests'.
+    actualCategory := testCaseHelper testCategory:'Some-Category-Tests'.    
+
+    self assert: expectedCategory equals: actualCategory.
+
+    "Created: / 30-08-2014 / 22:06:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-11-2014 / 21:13:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_test_category_ending_without_tests
+    | expectedCategory actualCategory |
+
+    expectedCategory := 'Some-Category-Tests'.
+    actualCategory := testCaseHelper testCategory:'Some-Category'.    
+
+    self assert: expectedCategory equals: actualCategory.
+
+    "Created: / 30-08-2014 / 22:07:13 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-11-2014 / 21:13:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseMethodCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,235 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseMethodCodeGenerator
+	instanceVariableNames:'testMethodSelectors'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+
+    ^ 'Creates test method for TestCase from method selection'
+
+    "Created: / 24-08-2014 / 16:16:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Testing')
+
+    "Created: / 05-08-2014 / 14:14:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'Test method'
+
+    "Created: / 24-08-2014 / 16:14:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ aCustomContext selectedMethods notEmptyOrNil
+
+    "Created: / 24-08-2014 / 16:18:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     to show"
+
+    ^ aCustomPerspective isMethodPerspective
+
+    "Created: / 24-08-2014 / 16:16:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'accessing'!
+
+testMethodSelector:aSelector 
+    "Returns how the test case method will be called for particular selector
+     belonging to method to be tested."
+    
+    ^ testMethodSelectors at:aSelector asSymbol ifAbsent: [ 
+        self createTestMethodSelectorFor: aSelector asSymbol  
+    ].
+
+    "Created: / 15-10-2014 / 08:19:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+testMethodSelector:aSelector put:aTestMethodName 
+    "Sets test method name - see testMethodName:."
+    
+    testMethodSelectors at:aSelector asSymbol put:aTestMethodName
+
+    "Created: / 15-10-2014 / 08:21:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'converting'!
+
+createTestMethodSelectorFor:aMethodSelector 
+    "Returns test method selector created from method selector to be tested"
+    
+    |testSelector|
+
+    testSelector := 'test_'.
+    aMethodSelector asString do:[:character | 
+        character isUppercase ifTrue:[
+            testSelector := testSelector , '_'.
+        ].
+        testSelector := testSelector , character asString toLowerCase
+    ].
+    testSelector replaceAll:$: with:$_.
+    ^testSelector
+
+    "Created: / 15-10-2014 / 09:04:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'executing - private'!
+
+buildInContext: aCustomContext
+
+    aCustomContext selectedMethods do:[ :method | 
+        | class className |
+
+        class := method mclass owningClassOrYourself.
+
+        className := class theNonMetaclass name.
+        (className endsWith: 'Tests') ifFalse: [ 
+            | testClass |
+
+            className := className, 'Tests'.
+            testClass := Smalltalk classNamed: className.
+            testClass notNil ifTrue: [ 
+                | testSelector |
+
+                testSelector := self testMethodSelector: method selector. 
+                (testClass includesSelector: testSelector asSymbol) ifFalse: [
+                    model createMethod
+                        package: method package;
+                        class: testClass;
+                        protocol: 'tests';
+                        source: (testSelector, '                            
+                            "/ something ', (method methodDefinitionTemplate asString), '.    
+                            self assert: 1 = 2.
+                        ');
+                        compile
+                ].
+            ].
+        ].
+    ].
+
+    "Created: / 24-08-2014 / 16:24:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-11-2014 / 15:01:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (format): / 25-01-2015 / 15:18:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+configureInContext:aCustomContext
+
+    aCustomContext selectedMethods do:[:selectedMethod |
+        | selector |
+
+        selector := selectedMethod selector asSymbol.
+        (testMethodSelectors includesKey: selector) ifFalse: [ 
+            testMethodSelectors 
+                at: selector 
+                put: (self createTestMethodSelectorFor: selector).
+        ].
+
+        dialog 
+            addSelectorNameEntryOn:(DictionaryAdaptor new
+                                        subject:testMethodSelectors; 
+                                        aspect:selector)
+            labeled:selector asString
+            validateBy:nil.
+    ].
+
+    dialog addButtons.
+    dialog open.
+
+    "Created: / 15-10-2014 / 08:59:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator methodsFor:'initialization'!
+
+initialize
+
+    super initialize.
+    testMethodSelectors := Dictionary new.
+
+    "Created: / 15-10-2014 / 08:22:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseMethodCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseMethodCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,106 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseMethodCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseMethodCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseMethodCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomTestCaseMethodCodeGenerator new
+! !
+
+!CustomTestCaseMethodCodeGeneratorTests methodsFor:'tests'!
+
+test_generate_test_method_for_class
+    | expectedSource method class testClass |
+
+    class := model createClassImmediate: #MockClassForTestCase01 superClassName: #Object.
+    testClass := model createClassImmediate: #MockClassForTestCase01Tests.
+    method := model createMethodImmediate: class source: 'selector_01 ^ 1'.
+
+    context selectedMethods: (Array with: method).  
+
+    expectedSource := 'test_selector_01
+    "/ something selector_01.    
+
+    self assert:1 = 2.'.
+
+    generatorOrRefactoring executeInContext: context.  
+
+    self assertMethodSource:expectedSource atSelector:#test_selector_01 forClass:testClass
+
+    "Created: / 29-11-2014 / 15:04:16 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_generate_test_method_for_private_class
+    | expectedSource privateClass method testClass |
+
+    model createClassImmediate: #MockClassForTestCase01 superClassName: #Object.
+    privateClass := model createClassImmediate: #PrivateClass01 superClassName: #MockClassForTestCase01 privateIn: #MockClassForTestCase01.
+    testClass := model createClassImmediate: #MockClassForTestCase01Tests.
+    method := model createMethodImmediate: privateClass source: 'selector_01 ^ 1'.
+
+    context selectedMethods: (Array with: method).  
+
+    expectedSource := 'test_selector_01
+    "/ something selector_01.    
+
+    self assert:1 = 2.'.
+
+    generatorOrRefactoring executeInContext: context.  
+
+    self assertMethodSource:expectedSource atSelector:#test_selector_01 forClass:testClass
+
+    "Created: / 31-10-2014 / 00:30:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:54:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseSetUpCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,180 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseSetUpCodeGenerator
+	instanceVariableNames:'samePackageAsTestedClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseSetUpCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseSetUpCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    ^ 'Generates initial #setUp for test cases'
+
+    "Modified: / 16-09-2014 / 11:24:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Testing')
+
+    "Created: / 05-08-2014 / 14:14:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    ^ 'TestCase setUp method'
+
+    "Modified: / 05-08-2014 / 14:13:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+    ^ aCustomContext selectedClasses anySatisfy: [:cls | cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ] ]
+
+    "Modified: / 12-06-2015 / 20:46:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+    ^ aCustomPerspective isClassPerspective
+
+    "Modified: / 05-08-2014 / 13:49:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator methodsFor:'accessing'!
+
+samePackageAsTestedClass
+    "Returns true when we should assign TestCase class 
+    to the same package as tested class."
+
+    ^ samePackageAsTestedClass
+
+    "Created: / 15-11-2014 / 11:54:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+samePackageAsTestedClass: aBoolean
+    "see samePackageAsTestedClass"
+
+    samePackageAsTestedClass := aBoolean
+
+    "Created: / 15-11-2014 / 11:56:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultSamePackageAsTestedClass
+    "default value for samePackageAsTestedClass"
+
+    ^ true
+
+    "Created: / 15-11-2014 / 12:21:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseSetUpCodeGenerator methodsFor:'executing'!
+
+buildForClass: class
+    | source category superHasSetup current package |
+
+    current := class.
+    superHasSetup := false.
+    [ superHasSetup not and:[ current isNil not ] ] whileTrue:[
+        superHasSetup := current includesSelector: #setUp.
+        superHasSetup ifFalse:[
+            current := current superclass.
+        ].
+    ].
+    superHasSetup ifTrue:[ 
+        source := 'setUp
+    super setUp.
+
+    "Add your own code here..."
+'.
+        category := (current compiledMethodAt: #setUp) category.
+    ] ifFalse:[ 
+        source := 'setUp
+    "/ super setUp.
+
+    "Add your own code here..."
+'.
+        category := (Smalltalk::TestCase compiledMethodAt: #setUp) category.
+    ].
+
+    package := PackageId noProjectID.
+    samePackageAsTestedClass ? self defaultSamePackageAsTestedClass ifTrue: [ 
+        package := class package
+    ].
+
+    model createMethod
+        class: class;
+        source: source;
+        category: category;
+        package: package;
+        compile.
+
+    "Created: / 05-08-2014 / 14:17:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-01-2015 / 18:32:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:46:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildInContext:aCustomContext
+    aCustomContext selectedClasses do:[:cls |  
+        (cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ]) ifTrue:[ 
+            self buildForClass: cls.
+        ].
+    ]
+
+    "Modified: / 12-06-2015 / 20:46:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseSetUpCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,184 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseSetUpCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseSetUpCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseSetUpCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomTestCaseSetUpCodeGenerator new
+! !
+
+!CustomTestCaseSetUpCodeGeneratorTests methodsFor:'tests'!
+
+test_set_up_method_generated_default_package
+    | expectedPackage class actualPackage |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        package: #dummy_package01;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedPackage := #dummy_package01.
+    generatorOrRefactoring executeInContext: context.
+    actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) package.  
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 31-01-2015 / 21:26:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_not_same_package
+    | expectedPackage class actualPackage |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        package: #dummy_package01;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedPackage := PackageId noProjectID.
+    generatorOrRefactoring samePackageAsTestedClass: false.  
+    generatorOrRefactoring executeInContext: context.
+    actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) package.  
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 31-01-2015 / 21:31:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_same_method_protocol  
+    | class expectedCategory actualCategory |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedCategory := (Smalltalk::TestCase compiledMethodAt: #setUp) category.
+    generatorOrRefactoring executeInContext: context.
+    actualCategory := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) category.
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 31-01-2015 / 21:36:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:46:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_same_package
+    | expectedPackage class actualPackage |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        package: #dummy_package01;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedPackage := #dummy_package01.
+    generatorOrRefactoring samePackageAsTestedClass: true.  
+    generatorOrRefactoring executeInContext: context.
+    actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #setUp) package.  
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 31-01-2015 / 21:30:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_set_up_implemented
+    | expectedSource class |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedSource := 'setUp
+    super setUp.
+
+    "Add your own code here..."'.
+    generatorOrRefactoring executeInContext: context.  
+    self assertMethodSource: expectedSource atSelector: #setUp forClass: class
+
+    "Created: / 31-01-2015 / 20:30:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_set_up_method_generated_set_up_not_implemented
+    | expectedSource class |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        compile;
+        yourself.
+
+    context selectedClasses: {class}.  
+
+    expectedSource := 'setUp
+    "/ super setUp.
+    "Add your own code here..."'.
+    generatorOrRefactoring buildForClass: class.  
+    self assertMethodSource: expectedSource atSelector: #setUp forClass: class
+
+    "Created: / 31-01-2015 / 20:30:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseTearDownCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,181 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomTestCaseTearDownCodeGenerator
+	instanceVariableNames:'samePackageAsTestedClass'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomTestCaseTearDownCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseTearDownCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    ^ 'Generates initial #tearDown for TestCases'
+
+    "Modified: / 05-08-2014 / 14:50:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Testing')
+
+    "Created: / 05-08-2014 / 14:14:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    ^ 'TestCase tearDown method'
+
+    "Modified: / 05-08-2014 / 14:51:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+    ^ aCustomContext selectedClasses anySatisfy: [:cls | cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ] ]
+
+    "Modified: / 12-06-2015 / 20:46:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective
+    ^ aCustomPerspective isClassPerspective
+
+    "Modified: / 05-08-2014 / 13:49:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator methodsFor:'accessing'!
+
+samePackageAsTestedClass
+    "Returns true when we should assign TestCase class 
+    to the same package as tested class."
+
+    ^ samePackageAsTestedClass
+
+    "Created: / 15-11-2014 / 11:54:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+samePackageAsTestedClass: aBoolean
+    "see samePackageAsTestedClass"
+
+    samePackageAsTestedClass := aBoolean
+
+    "Created: / 15-11-2014 / 11:56:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultSamePackageAsTestedClass
+    "default value for samePackageAsTestedClass"
+
+    ^ true
+
+    "Created: / 15-11-2014 / 12:21:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomTestCaseTearDownCodeGenerator methodsFor:'executing'!
+
+buildForClass: class
+    | source category superHasSetup current package |
+
+    current := class.
+    superHasSetup := false.
+    [ superHasSetup not and:[ current isNil not ] ] whileTrue:[
+        superHasSetup := current includesSelector: #tearDown.
+        superHasSetup ifFalse:[
+            current := current superclass.
+        ].
+
+    ].
+    superHasSetup ifTrue:[ 
+        source := 'tearDown
+    "Add your own code here..."
+
+    super tearDown.  
+'.
+        category := (current compiledMethodAt: #tearDown) category.
+    ] ifFalse:[ 
+        source := 'tearDown
+    "Add your own code here..."
+
+    "/ super tearDown.
+'.
+        category := (Smalltalk::TestCase compiledMethodAt: #tearDown ) category.
+    ].
+
+    package := PackageId noProjectID.
+    samePackageAsTestedClass ? self defaultSamePackageAsTestedClass ifTrue: [ 
+        package := class package
+    ].
+
+    model createMethod
+        class: class;
+        source: source;
+        category: category;
+        package: package;
+        compile.
+
+    "Created: / 05-08-2014 / 14:17:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-01-2015 / 18:34:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:46:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+buildInContext:aCustomContext
+    aCustomContext selectedClasses do:[:cls |  
+        (cls isMetaclass not and:[ cls inheritsFrom: Smalltalk::TestCase ]) ifTrue:[ 
+            self buildForClass: cls.
+        ].
+    ]
+
+    "Modified: / 12-06-2015 / 20:44:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomTestCaseTearDownCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,184 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomTestCaseTearDownCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomTestCaseTearDownCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomTestCaseTearDownCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomTestCaseTearDownCodeGenerator new
+! !
+
+!CustomTestCaseTearDownCodeGeneratorTests methodsFor:'tests'!
+
+test_tear_down_method_generated_default_package
+    | expectedPackage class actualPackage |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        package: #dummy_package01;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedPackage := #dummy_package01.
+    generatorOrRefactoring executeInContext: context.
+    actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) package.  
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 31-01-2015 / 21:41:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_not_same_package
+    | expectedPackage class actualPackage |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        package: #dummy_package01;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedPackage := PackageId noProjectID.
+    generatorOrRefactoring samePackageAsTestedClass: false.  
+    generatorOrRefactoring executeInContext: context.
+    actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) package.  
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 31-01-2015 / 21:42:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_same_method_protocol  
+    | class expectedCategory actualCategory |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedCategory := (Smalltalk::TestCase compiledMethodAt: #tearDown) category.
+    generatorOrRefactoring executeInContext: context.
+    actualCategory := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) category.
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 31-01-2015 / 21:42:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:47:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_same_package
+    | expectedPackage class actualPackage |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        package: #dummy_package01;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedPackage := #dummy_package01.
+    generatorOrRefactoring samePackageAsTestedClass: true.  
+    generatorOrRefactoring executeInContext: context.
+    actualPackage := ((Smalltalk at: #DummyTestCase01) compiledMethodAt: #tearDown) package.  
+    self assert: expectedPackage = actualPackage
+
+    "Created: / 31-01-2015 / 21:42:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_tear_down_implemented
+    | expectedSource class |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        superclassName: #TestCase;
+        compile;
+        yourself. 
+
+    context selectedClasses: {class}.  
+
+    expectedSource := 'tearDown
+    "Add your own code here..."
+
+    super tearDown.'.
+    generatorOrRefactoring executeInContext: context.  
+    self assertMethodSource: expectedSource atSelector: #tearDown forClass: class
+
+    "Created: / 31-01-2015 / 21:42:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_tear_down_method_generated_tear_down_not_implemented
+    | expectedSource class |
+
+    class := model createClass
+        name: #DummyTestCase01;
+        compile;
+        yourself.
+
+    context selectedClasses: {class}.  
+
+    expectedSource := 'tearDown
+    "Add your own code here..."
+    "/ super tearDown.'.
+    generatorOrRefactoring buildForClass: class.  
+    self assertMethodSource: expectedSource atSelector: #tearDown forClass: class
+
+    "Created: / 31-01-2015 / 21:41:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUITestCaseCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,92 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomTestCaseCodeGenerator subclass:#CustomUITestCaseCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomUITestCaseCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomUITestCaseCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    ^ 'Creates a new test case for UI'
+
+    "Created: / 16-09-2014 / 11:33:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+
+    ^ 'New UI Test Case'
+
+    "Created: / 16-09-2014 / 11:23:32 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomUITestCaseCodeGenerator methodsFor:'accessing - defaults'!
+
+defaultGenerateSetUp
+    ^ true
+
+    "Created: / 16-09-2014 / 11:26:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+defaultSetUpCodeGeneratorClass
+    ^ CustomUITestCaseSetUpCodeGenerator
+
+    "Created: / 16-09-2014 / 11:20:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomUITestCaseCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUITestCaseSetUpCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,68 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomTestCaseSetUpCodeGenerator subclass:#CustomUITestCaseSetUpCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomUITestCaseSetUpCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomUITestCaseSetUpCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    ^ 'Generates initial #setUp for UI test cases'
+
+    "Created: / 16-09-2014 / 11:24:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    ^ 'TestCase setUp method (for UI Test Cases)'
+
+    "Created: / 16-09-2014 / 11:23:50 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUpdateTestCaseCategoryRefactoring.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,126 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomRefactoring subclass:#CustomUpdateTestCaseCategoryRefactoring
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings'
+!
+
+!CustomUpdateTestCaseCategoryRefactoring class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoring class methodsFor:'accessing-presentation'!
+
+description
+
+    ^ 'Updates TestCase subclasses category with respect to their classes to be tested'
+
+    "Modified: / 08-11-2014 / 18:49:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+
+    ^ 'Update TestCase Category'
+
+    "Modified: / 08-11-2014 / 17:28:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoring class methodsFor:'queries'!
+
+availableForClass:aClass
+
+    ^ (aClass isSubclassOf: Smalltalk::TestCase) and: [ 
+        aClass theNonMetaclass name endsWith: 'Tests'  
+    ]
+
+    "Created: / 08-11-2014 / 19:03:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:43:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+availableInContext:aCustomContext 
+
+    ^ aCustomContext selectedClasses ? #() anySatisfy: [ :class |
+        self availableForClass: class
+    ]
+
+    "Modified: / 25-01-2015 / 15:10:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective: aCustomPerspective 
+
+    ^ aCustomPerspective isClassPerspective
+
+    "Modified: / 08-11-2014 / 17:27:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoring methodsFor:'executing - private'!
+
+buildInContext: aCustomContext 
+    | testCaseHelper |
+
+    testCaseHelper := CustomTestCaseHelper new.
+
+    aCustomContext selectedClasses ? #() do:[ :class | 
+        (self class availableForClass: class) ifTrue: [ 
+            | testedClassName |
+
+            testedClassName := (class theNonMetaclass name removeSuffix: 'Tests') asSymbol.
+            (model includesClassNamed: testedClassName) ifTrue: [
+                | testCategory |
+
+                testCategory := testCaseHelper 
+                    testCategory: (model classNamed: testedClassName) category.
+
+                (testCategory = (class category)) ifFalse: [ 
+                    refactoryBuilder changeCategoryOf: class to: testCategory
+                ]
+            ]
+        ]
+    ]
+
+    "Modified: / 08-11-2014 / 21:33:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUpdateTestCaseCategoryRefactoringTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,227 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomUpdateTestCaseCategoryRefactoringTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Refactorings-Tests'
+!
+
+!CustomUpdateTestCaseCategoryRefactoringTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomUpdateTestCaseCategoryRefactoringTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomUpdateTestCaseCategoryRefactoring new
+! !
+
+!CustomUpdateTestCaseCategoryRefactoringTests methodsFor:'tests'!
+
+test_available_for_class_fake_test
+
+    |class|
+
+    class := model createClassImmediate: #Dummy01Tests.  
+
+    self deny: (generatorOrRefactoring class availableForClass: class).
+
+    "Created: / 08-11-2014 / 23:40:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_class_object
+    
+    self deny: (generatorOrRefactoring class availableForClass: Object).
+
+    "Created: / 08-11-2014 / 23:40:01 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_for_class_test_case
+    
+    self assert: (generatorOrRefactoring class availableForClass: self class).
+
+    "Modified: / 08-11-2014 / 23:39:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_empty
+    
+    self deny: (generatorOrRefactoring class availableInContext: context).
+
+    "Modified: / 08-11-2014 / 23:42:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_with_test_class
+
+    context selectedClasses: (Array with: Object with: self class).  
+
+    self assert: (generatorOrRefactoring class availableInContext: context).
+
+    "Created: / 08-11-2014 / 23:43:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_context_without_test_class
+
+    context selectedClasses: (Array with: Object).  
+
+    self deny: (generatorOrRefactoring class availableInContext: context).
+
+    "Created: / 08-11-2014 / 23:44:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_available_in_perspective
+    
+    self assert: (generatorOrRefactoring class availableInPerspective: CustomPerspective classPerspective).
+
+    "Modified: / 08-11-2014 / 23:45:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_model_classes
+    | expectedCategory actualCategory testClass |
+
+    model createClass
+        name: #DummyClass01;
+        category: #Category01;
+        compile.
+
+    testClass := model createClass
+        name: #DummyClass01Tests;
+        superclassName: #TestCase;
+        category: #Category02;
+        compile;
+        yourself.  
+
+    expectedCategory := #'Category01-Tests'.
+
+    context selectedClasses: (Array with: testClass).  
+
+    generatorOrRefactoring executeInContext: context.
+
+    actualCategory := testClass category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 08-11-2014 / 23:57:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:16:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_model_classes_category_ok
+    | expectedCategory actualCategory testClass |
+
+    model createClass
+        name: #DummyClass01;
+        category: #Category01;
+        compile.
+
+    testClass := model createClass
+        name: #DummyClass01Tests;
+        superclassName: #TestCase;
+        category: #'Category01-Tests';
+        compile;
+        yourself.  
+
+    expectedCategory := #'Category01-Tests'.
+
+    context selectedClasses: (Array with: testClass).  
+
+    generatorOrRefactoring executeInContext: context.
+
+    actualCategory := testClass category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 08-11-2014 / 23:58:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:16:32 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_model_classes_wrong_suffix
+    | expectedCategory actualCategory testClass |
+
+    model createClass
+        name: #DummyClass01;
+        category: #Category01;
+        compile.
+
+    testClass := model createClass
+        name: #DummyClass01Tested;
+        superclassName: #TestCase;
+        category: #Category01;
+        compile;
+        yourself.  
+
+    expectedCategory := #Category01.
+
+    context selectedClasses: (Array with: testClass).  
+
+    generatorOrRefactoring executeInContext: context.
+
+    actualCategory := testClass category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 09-11-2014 / 00:01:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 16:16:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_category_updated_real_classes
+    | expectedCategory actualCategory testClass |
+
+    model createClassImmediate: #DummyClass01 category: #Category01.
+    testClass := model createClassImmediate: #DummyClass01Tests superClassName: #TestCase.
+    testClass category: #Category02.  
+
+    expectedCategory := #'Category01-Tests'.
+
+    context selectedClasses: (Array with: testClass).  
+
+    generatorOrRefactoring executeInContext: context.
+
+    actualCategory := testClass category.
+
+    self assert: expectedCategory = actualCategory
+
+    "Created: / 08-11-2014 / 23:53:04 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:54:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomUserDialog.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,166 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomDialog subclass:#CustomUserDialog
+	instanceVariableNames:'dialog'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-UI'
+!
+
+!CustomUserDialog class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+    CustomDialog implementation with real dialogs to provide human interaction.
+    Currently it is a simple wrapper around DialogBox. 
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+
+"
+! !
+
+!CustomUserDialog class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
+!CustomUserDialog methodsFor:'accessing'!
+
+dialog
+    ^ dialog
+!
+
+dialog:something
+    dialog := something.
+! !
+
+!CustomUserDialog methodsFor:'construction-adding'!
+
+addAbortAndOkButtons
+    "Adds buttons Ok and Cancel"
+
+    dialog addAbortAndOkButtons
+
+    "Created: / 15-09-2014 / 16:21:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 09-11-2014 / 22:52:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+addComponent:aView
+    "Add given component. Component is automatically stretched to occupy windows' width"
+
+    ^ dialog addComponent: aView
+
+    "Created: / 15-09-2014 / 18:50:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+addComponent:aView labeled:aString
+    "Add a label and some component side-by-side. Returns the component"
+
+"/    aString notEmptyOrNil ifTrue:[
+        ^ dialog
+            addLabelledField:aView 
+            label:aString ? ''
+            adjust:#left 
+            tabable:true 
+            separateAtX:0.3
+"/    ] ifFalse:[ 
+"/        ^ dialog
+"/            addComponent:aView indent: 0.3
+"/    ].
+
+    "Created: / 15-09-2014 / 15:45:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 15-09-2014 / 19:44:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!CustomUserDialog methodsFor:'initialization'!
+
+initialize
+
+    dialog := DialogBox new
+
+    "Modified: / 15-09-2014 / 16:23:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 21:09:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUserDialog methodsFor:'opening'!
+
+open
+    "Actually opens the dialog. Return true, if dialog has been accepted
+     of raises abort request if it has been cancelled."
+
+    dialog open.
+    dialog accepted ifFalse: [
+        AbortOperationRequest raiseRequest
+    ].
+
+    ^ dialog accepted
+
+    "Created: / 15-09-2014 / 16:23:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 14-11-2014 / 17:52:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 25-11-2014 / 21:08:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUserDialog methodsFor:'user interaction & notifications'!
+
+information: aString
+
+    ^ Dialog information: aString
+
+    "Created: / 02-06-2014 / 22:36:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 22-07-2014 / 21:25:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomUserDialog class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderAccessMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderAccessMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Access Method(s) for ValueHolder and selected instance variables'
+
+    "Modified: / 13-07-2014 / 17:00:47 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Access Method(s) for ValueHolder'
+
+    "Modified: / 13-07-2014 / 17:00:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Creates access methods XX for given context"
+
+    self executeSubGeneratorOrRefactoringClasses:(Array 
+                  with:CustomValueHolderGetterMethodsCodeGenerator
+                  with:CustomSimpleSetterMethodsCodeGenerator)
+          inContext:aCustomContext
+
+    "Modified: / 13-07-2014 / 16:59:23 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderAccessMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,114 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderAccessMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomValueHolderAccessMethodsCodeGenerator new
+! !
+
+!CustomValueHolderAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_access_methods_generated_with_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: true;
+        generateCommentsForSetters: true.
+
+    expectedGetterSource := 'instanceVariable
+    "return/create the ''instanceVariable'' value holder (automatically generated)"
+
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+    ].
+    ^ instanceVariable'. 
+
+    expectedSetterSource := 'instanceVariable:something
+    "set the value of the instance variable ''instanceVariable'' (automatically generated)"
+
+    instanceVariable := something'.
+
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 13-07-2014 / 17:02:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_access_methods_generated_without_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: false;
+        generateCommentsForSetters: false.
+
+    expectedGetterSource := 'instanceVariable
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+    ].
+    ^ instanceVariable'. 
+
+    expectedSetterSource := 'instanceVariable:something
+    instanceVariable := something'.
+
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 13-07-2014 / 17:03:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderGetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,126 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderGetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+    ^ 'Getter methods with ValueHolder for selected instance variables'
+
+    "Created: / 19-05-2014 / 20:56:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 30-06-2014 / 19:44:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Getters')
+
+    "Created: / 22-08-2014 / 18:55:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+    ^ 'Getter Method(s) for ValueHolder'
+
+    "Created: / 19-05-2014 / 20:56:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderGetterMethodsCodeGenerator methodsFor:'accessing'!
+
+protocol
+    "Returns protocol name in which will belong getter method"
+
+    ^ 'aspects'
+
+    "Created: / 19-05-2014 / 20:59:12 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns getter method source code with ValueHolder for given class and variable name"
+
+    | methodName comment |
+
+    methodName := self methodNameFor: aName.
+    comment := ''.
+
+    userPreferences generateCommentsForGetters ifTrue:[
+        comment := '"return/create the ''%1'' value holder (automatically generated)"'.
+        comment := comment bindWith: aName.
+    ].  
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+            `"comment
+
+            `variableName isNil ifTrue:[
+                `variableName := ValueHolder new.
+            ].
+            ^ `variableName';
+        replace: '`@methodName' with: methodName asSymbol;
+        replace: '`variableName' with: aName asString;
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Created: / 19-05-2014 / 20:52:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-09-2014 / 22:36:39 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderGetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderGetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomValueHolderGetterMethodsCodeGenerator new
+! !
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_getter_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: true.
+
+    expectedSource := 'instanceVariable
+    "return/create the ''instanceVariable'' value holder (automatically generated)"
+
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+    ].
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 14-06-2014 / 11:34:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-06-2014 / 22:44:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_getter_method_generated_without_comments
+    | expectedSource |    
+
+    userPreferences generateCommentsForGetters: false.
+
+    expectedSource := 'instanceVariable
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+    ].
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 14-06-2014 / 11:36:51 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-06-2014 / 22:12:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,86 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Access Method(s) for ValueHolder with Change Notification for selected instance variables'
+
+    "Modified: / 13-07-2014 / 17:13:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Access Method(s) for ValueHolder with Change Notification'
+
+    "Modified: / 13-07-2014 / 17:13:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Creates access methods XX for given context"
+
+    self executeSubGeneratorOrRefactoringClasses:(Array 
+                  with:CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator
+                  with:CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator)
+          inContext:aCustomContext
+
+    "Modified: / 13-07-2014 / 17:12:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,153 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator new
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_access_methods_generated_with_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: true;
+        generateCommentsForSetters: true.
+
+    expectedGetterSource := 'instanceVariable
+    "return/create the ''instanceVariable'' value holder with change notification (automatically generated)"
+
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+        instanceVariable addDependent:self.
+    ].
+    ^ instanceVariable'. 
+
+    expectedSetterSource := 'instanceVariable:something
+    "set the ''instanceVariable'' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    instanceVariable notNil ifTrue:[
+        oldValue := instanceVariable value.
+        instanceVariable removeDependent:self.
+    ].
+    instanceVariable := something.
+    instanceVariable notNil ifTrue:[
+        instanceVariable addDependent:self.
+    ].
+    newValue := instanceVariable value.
+    oldValue ~~ newValue ifTrue:[
+        self
+            update:#value
+            with:newValue
+            from:instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 13-07-2014 / 17:16:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_access_methods_generated_without_comments
+    | expectedGetterSource expectedSetterSource |
+
+    userPreferences
+        generateCommentsForGetters: false;
+        generateCommentsForSetters: false.
+
+    expectedGetterSource := 'instanceVariable
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+        instanceVariable addDependent:self.
+    ].
+    ^ instanceVariable'. 
+
+    expectedSetterSource := 'instanceVariable:something
+    |oldValue newValue|
+
+    instanceVariable notNil ifTrue:[
+        oldValue := instanceVariable value.
+        instanceVariable removeDependent:self.
+    ].
+    instanceVariable := something.
+    instanceVariable notNil ifTrue:[
+        instanceVariable addDependent:self.
+    ].
+    newValue := instanceVariable value.
+    oldValue ~~ newValue ifTrue:[
+        self
+            update:#value
+            with:newValue
+            from:instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedGetterSource atSelector: #instanceVariable.
+    self assertMethodSource: expectedSetterSource atSelector: #instanceVariable:
+
+    "Created: / 13-07-2014 / 17:23:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,133 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+
+    ^ 'Getter methods with ValueHolder and change notification for selected instance variables'
+
+    "Created: / 30-06-2014 / 19:31:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Getters')
+
+    "Created: / 22-08-2014 / 18:55:37 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+
+    ^ 'Getter Method(s) for ValueHolder with Change Notification'
+
+    "Created: / 30-06-2014 / 19:36:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator methodsFor:'accessing'!
+
+protocol
+    "Returns protocol name in which will belong getter method"
+
+    ^ 'aspects'
+
+    "Created: / 30-06-2014 / 19:48:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns getter method source code with ValueHolder and change notification for given class and variable name"
+
+    | methodName comment |
+
+    methodName := self methodNameFor: aName.
+    comment := ''.
+
+    userPreferences generateCommentsForGetters ifTrue:[
+        comment := '"return/create the ''%1'' value holder with change notification (automatically generated)"'.
+        comment := comment bindWith: aName.
+    ].  
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+            `"comment
+
+            `variableName isNil ifTrue:[
+                `variableName := ValueHolder new.
+                `variableName addDependent: self.
+            ].
+            ^ `variableName';
+        replace: '`@methodName' with: methodName asSymbol;
+        replace: '`variableName' with: aName asString;
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Created: / 30-06-2014 / 19:18:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 19-09-2014 / 22:37:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,107 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator new
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_getter_with_change_notification_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: true.
+
+    expectedSource := 'instanceVariable
+    "return/create the ''instanceVariable'' value holder with change notification (automatically generated)"
+
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+        instanceVariable addDependent:self.
+    ].
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 30-06-2014 / 19:54:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_getter_with_change_notification_method_generated_without_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForGetters: false.
+
+    expectedSource := 'instanceVariable
+    instanceVariable isNil ifTrue:[
+        instanceVariable := ValueHolder new.
+        instanceVariable addDependent:self.
+    ].
+    ^ instanceVariable'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable
+
+    "Created: / 30-06-2014 / 19:56:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,129 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomAccessMethodsCodeGenerator subclass:#CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator class methodsFor:'accessing-presentation'!
+
+description
+    "Returns more detailed description of the receiver"
+    
+    ^ 'Setter methods for ValueHolder with Change Notification for selected instance variables'
+
+    "Modified: / 07-07-2014 / 00:02:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+group
+    "Returns a collection strings describing a group to which
+     receiver belongs. A groups may be nested hence the array of
+     strings. For example for subgroup 'Accessors' in group 'Generators'
+     this method should return #('Generators' 'Accessors')."
+
+    "/ By default return an empty array which means the item will appear
+    "/ in top-level group.
+    ^ #('Accessors' 'Setters')
+
+    "Created: / 22-08-2014 / 18:55:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    "Returns show label describing the receiver. This label
+     is used in UI as menu item/tree item label."
+    
+    ^ 'Setter Method(s) for ValueHolder with Change Notification'
+
+    "Modified: / 06-07-2014 / 23:59:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator methodsFor:'code generation'!
+
+sourceForClass: aClass variableName: aName
+    "Returns setter method for ValueHolder with change notification for given class and variable name"
+
+    | methodName comment argName |
+
+    methodName := self methodNameFor: aName.
+    argName := self argNameForMethodName: methodName.  
+    comment := ''.
+
+    userPreferences generateCommentsForSetters ifTrue:[
+        comment := '"set the ''%1'' value holder (automatically generated)"'.
+        comment := comment bindWith: aName.
+    ].
+
+    ^ self sourceCodeGenerator
+        source: '`@methodName
+            `"comment
+
+            | oldValue newValue |
+
+            `variableName notNil ifTrue:[
+                oldValue := `variableName value.
+                `variableName removeDependent: self.
+            ].
+            `variableName := `argName.
+            `variableName notNil ifTrue:[
+                `variableName addDependent: self.
+            ].
+            newValue := `variableName value.
+            oldValue ~~ newValue ifTrue:[
+                self update:#value with:newValue from:`variableName.
+            ].';
+        replace: '`@methodName' with: (methodName, ': ', argName) asSymbol;
+        replace: '`argName' with: argName asString;
+        replace: '`variableName' with: aName asString;
+        replace: '`"comment' with: comment;
+        newSource.
+
+    "Modified: / 19-09-2014 / 22:37:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,131 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator new
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests methodsFor:'tests'!
+
+test_value_holder_with_change_notification_setter_method_generated_with_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: true.
+
+    expectedSource := 'instanceVariable:something
+    "set the ''instanceVariable'' value holder (automatically generated)"
+
+    |oldValue newValue|
+
+    instanceVariable notNil ifTrue:[
+        oldValue := instanceVariable value.
+        instanceVariable removeDependent:self.
+    ].
+    instanceVariable := something.
+    instanceVariable notNil ifTrue:[
+        instanceVariable addDependent:self.
+    ].
+    newValue := instanceVariable value.
+    oldValue ~~ newValue ifTrue:[
+        self
+            update:#value
+            with:newValue
+            from:instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+    "Created: / 07-07-2014 / 00:24:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_value_holder_with_change_notification_setter_method_generated_without_comments
+    | expectedSource |
+
+    userPreferences generateCommentsForSetters: false.
+
+    expectedSource := 'instanceVariable:something
+    |oldValue newValue|
+
+    instanceVariable notNil ifTrue:[
+        oldValue := instanceVariable value.
+        instanceVariable removeDependent:self.
+    ].
+    instanceVariable := something.
+    instanceVariable notNil ifTrue:[
+        instanceVariable addDependent:self.
+    ].
+    newValue := instanceVariable value.
+    oldValue ~~ newValue ifTrue:[
+        self
+            update:#value
+            with:newValue
+            from:instanceVariable.
+    ].'.
+
+    self executeGeneratorInContext: #classWithInstanceVariable.
+    self assertMethodSource: expectedSource atSelector: #instanceVariable:
+
+    "Created: / 07-07-2014 / 00:23:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGenerator.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,152 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGenerator subclass:#CustomVisitorCodeGenerator
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomVisitorCodeGenerator class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomVisitorCodeGenerator class methodsFor:'accessing'!
+
+description
+    ^ 'Generate methods for visitor pattern'.
+
+    "Created: / 24-07-2013 / 16:39:23 / user"
+    "Modified: / 01-12-2013 / 00:22:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+label
+    ^ 'Visitor and Visited Methods'.
+
+    "Created: / 01-12-2013 / 00:22:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-02-2014 / 22:40:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomVisitorCodeGenerator class methodsFor:'queries'!
+
+availableInContext:aCustomContext
+    "Returns true if the generator/refactoring is available in given
+     context, false otherwise.
+     
+     Called by the UI to figure out what generators / refactorings
+     are available at given point. See class CustomContext for details."
+
+    ^ aCustomContext selectedClasses notEmptyOrNil
+
+    "Modified: / 23-02-2014 / 22:32:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+availableInPerspective:aCustomPerspective 
+    "Returns true if the generator/refactoring is available in given
+     perspective, false otherwise.
+
+     Called by the UI to figure out what generators / refactorings
+     to show"
+    
+    ^ aCustomPerspective isClassPerspective
+
+    "Created: / 26-01-2014 / 21:40:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 23-02-2014 / 22:33:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+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 == CustomVisitorCodeGenerator.
+! !
+
+!CustomVisitorCodeGenerator methodsFor:'code generation-individual methods'!
+
+buildAcceptVisitorMethod: selector withParameter: withParameter forClass: aClass
+    "Creates an acceptVisitor: method"
+
+    | comment parameterSelectorPart methodSelector |
+
+    comment := ''.
+    userPreferences generateComments ifTrue: [ 
+        comment := '"Double dispatch back to the visitor, passing my type encoded in
+     the selector (visitor pattern)"     
+
+    "stub code automatically generated - please change if required"'.
+    ].
+
+    methodSelector := 'acceptVisitor: visitor'.
+    parameterSelectorPart := ''.
+    withParameter ifTrue: [ 
+        parameterSelectorPart := ' with: parameter'.
+        methodSelector := methodSelector, parameterSelectorPart.
+    ].
+
+    model createMethod
+        class: aClass;
+        protocol: 'visiting';
+        source: ('`@methodSelector
+            `"comment
+
+            ^ visitor `@selector self `@parameterSelectorPart       
+        ');
+        replace: '`@methodSelector' with: methodSelector;
+        replace: '`@selector' with: selector asSymbol;
+        replace: '`"comment' with: comment;
+        replace: '`@parameterSelectorPart' with: parameterSelectorPart;
+        compile.
+
+    "Created: / 27-07-2014 / 01:08:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 08-10-2014 / 14:47:43 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomVisitorCodeGenerator class methodsFor:'documentation'!
+
+version_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,89 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomVisitorCodeGenerator subclass:#CustomVisitorCodeGeneratorAcceptVisitor
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators'
+!
+
+!CustomVisitorCodeGeneratorAcceptVisitor class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitor class methodsFor:'accessing'!
+
+description
+    ^ 'Method for visitor pattern - acceptVisitor'.
+
+    "Created: / 09-03-2014 / 20:38:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 27-07-2014 / 00:58:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+label
+    ^ 'Visitor Method'.
+
+    "Created: / 09-03-2014 / 20:38:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitor methodsFor:'executing'!
+
+buildInContext: aCustomContext
+    "Builds acceptVisitor method"
+
+    aCustomContext selectedClasses do: [ :class | 
+        | selector |
+
+        selector := ('visit', class nameWithoutPrefix) asMutator.
+
+        self
+            buildAcceptVisitorMethod: selector
+            withParameter: false
+            forClass: class
+    ].
+
+    "Created: / 19-03-2014 / 18:32:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 03-08-2014 / 23:31:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGeneratorAcceptVisitorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,96 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomVisitorCodeGeneratorAcceptVisitorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomVisitorCodeGeneratorAcceptVisitorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomVisitorCodeGeneratorAcceptVisitor new
+! !
+
+!CustomVisitorCodeGeneratorAcceptVisitorTests methodsFor:'tests'!
+
+test_accept_visitor_method_generated_with_comments
+    |expectedSource|
+
+    userPreferences generateComments: true.  
+
+    expectedSource := 'acceptVisitor:visitor
+    "Double dispatch back to the visitor, passing my type encoded in
+the selector (visitor pattern)"
+    "stub code automatically generated - please change if required"
+
+    ^ visitor visitDummyClassForGeneratorTestCase:self'.
+
+    self executeGeneratorInContext:#classWithInstanceVariable.
+    self assertMethodSource:expectedSource atSelector:#acceptVisitor:
+
+    "Created: / 03-08-2014 / 23:06:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 21:00:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_without_comments
+    |expectedSource|
+
+    userPreferences generateComments: false.  
+
+    expectedSource := 'acceptVisitor:visitor
+    ^ visitor visitDummyClassForGeneratorTestCase:self'.
+
+    self executeGeneratorInContext:#classWithInstanceVariable.
+    self assertMethodSource:expectedSource atSelector:#acceptVisitor:
+
+    "Created: / 03-08-2014 / 23:33:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 21:13:41 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/SmallSense__CustomVisitorCodeGeneratorTests.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,166 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: SmallSense }"
+
+CustomCodeGeneratorOrRefactoringTestCase subclass:#CustomVisitorCodeGeneratorTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Interface-Refactoring-Custom-Generators-Tests'
+!
+
+!CustomVisitorCodeGeneratorTests class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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
+"
+! !
+
+!CustomVisitorCodeGeneratorTests methodsFor:'accessing'!
+
+generatorOrRefactoring
+    ^ CustomVisitorCodeGenerator new
+! !
+
+!CustomVisitorCodeGeneratorTests methodsFor:'tests'!
+
+test_accept_visitor_method_generated_with_comment_and_with_parameter
+    "check if methods for visitor pattern are correctly generated"
+    | expectedSource class |
+
+    userPreferences generateComments: true.
+
+    expectedSource := 'acceptVisitor:visitor with:parameter 
+    "Double dispatch back to the visitor, passing my type encoded in
+the selector (visitor pattern)"
+    "stub code automatically generated - please change if required"
+
+    ^ visitor visitDummyTestClassForVisitorMethod:self with:parameter'.
+
+    class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+    generatorOrRefactoring
+        buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+        withParameter: true 
+        forClass: class.
+
+    generatorOrRefactoring model execute.
+
+    self assertMethodSource: expectedSource atSelector: #acceptVisitor:with: forClass: class
+
+    "Created: / 27-07-2014 / 12:32:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 20:59:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_with_comment_and_without_parameter
+    "check if methods for visitor pattern are correctly generated"
+    | expectedSource class |
+
+    userPreferences generateComments: true.
+
+    expectedSource := 'acceptVisitor:visitor 
+    "Double dispatch back to the visitor, passing my type encoded in
+the selector (visitor pattern)"
+    "stub code automatically generated - please change if required"
+
+    ^ visitor visitDummyTestClassForVisitorMethod:self'.
+
+    class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+    generatorOrRefactoring
+        buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+        withParameter: false 
+        forClass: class.
+
+    generatorOrRefactoring model execute.
+
+    self assertMethodSource: expectedSource atSelector: #acceptVisitor: forClass: class
+
+    "Created: / 03-08-2014 / 22:50:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 20:59:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_without_comment_and_with_parameter
+    "check if methods for visitor pattern are correctly generated"
+    | expectedSource class |
+
+    userPreferences generateComments: false.
+
+    expectedSource := 'acceptVisitor:visitor with:parameter 
+    ^ visitor visitDummyTestClassForVisitorMethod:self with:parameter'.
+
+    class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+    generatorOrRefactoring
+        buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+        withParameter: true 
+        forClass: class.
+
+    generatorOrRefactoring model execute.
+
+    self assertMethodSource: expectedSource atSelector: #acceptVisitor:with: forClass: class
+
+    "Created: / 03-08-2014 / 22:53:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 20:59:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+!
+
+test_accept_visitor_method_generated_without_comment_and_without_parameter
+    "check if methods for visitor pattern are correctly generated"
+    | expectedSource class |
+
+    userPreferences generateComments: false.  
+
+    expectedSource := 'acceptVisitor:visitor
+    ^ visitor visitDummyTestClassForVisitorMethod:self'.
+
+    class := model createClassImmediate: 'DummyTestClassForVisitorMethod'.
+
+    generatorOrRefactoring
+        buildAcceptVisitorMethod: 'visitDummyTestClassForVisitorMethod:'
+        withParameter: false 
+        forClass: class.
+
+    generatorOrRefactoring model execute.
+
+    self assertMethodSource: expectedSource atSelector: #acceptVisitor: forClass: class
+
+    "Created: / 03-08-2014 / 22:51:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-08-2014 / 21:00:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/abbrev.stc	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,127 @@
+# 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::CustomBrowserEnvironmentTests SmallSense__CustomBrowserEnvironmentTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomChangeManager SmallSense__CustomChangeManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomClassQuery SmallSense__CustomClassQuery stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers' 0
+SmallSense::CustomClassQueryTests SmallSense__CustomClassQueryTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers-Tests' 1
+SmallSense::CustomCodeGeneratorOrRefactoring SmallSense__CustomCodeGeneratorOrRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomCodeGeneratorOrRefactoringTestCase SmallSense__CustomCodeGeneratorOrRefactoringTestCase stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomContext SmallSense__CustomContext stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomContextTests SmallSense__CustomContextTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomDialog SmallSense__CustomDialog stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomLocalChangeManagerTests SmallSense__CustomLocalChangeManagerTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomManager SmallSense__CustomManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomManagerTests SmallSense__CustomManagerTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomMenuBuilder SmallSense__CustomMenuBuilder stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomMenuBuilderTests SmallSense__CustomMenuBuilderTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI-Tests' 1
+SmallSense::CustomMock SmallSense__CustomMock stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 0
+SmallSense::CustomMockTests SmallSense__CustomMockTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomNamespace SmallSense__CustomNamespace stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomNewSystemBrowserTests SmallSense__CustomNewSystemBrowserTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI-Tests' 1
+SmallSense::CustomNoneSourceCodeFormatterTests SmallSense__CustomNoneSourceCodeFormatterTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomParseTreeRewriter SmallSense__CustomParseTreeRewriter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomParseTreeRewriterTests SmallSense__CustomParseTreeRewriterTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomPerspective SmallSense__CustomPerspective stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 1
+SmallSense::CustomPerspectiveTests SmallSense__CustomPerspectiveTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBAbstractClassTests SmallSense__CustomRBAbstractClassTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBClassTests SmallSense__CustomRBClassTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBLocalSourceCodeFormatterTests SmallSense__CustomRBLocalSourceCodeFormatterTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBMetaclassTests SmallSense__CustomRBMetaclassTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRBMethodTests SmallSense__CustomRBMethodTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomRefactoryBuilder SmallSense__CustomRefactoryBuilder stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomRefactoryClassChangeTests SmallSense__CustomRefactoryClassChangeTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomSourceCodeFormatter SmallSense__CustomSourceCodeFormatter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSourceCodeGenerator SmallSense__CustomSourceCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSourceCodeGeneratorTests SmallSense__CustomSourceCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomSourceCodeSelection SmallSense__CustomSourceCodeSelection stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSourceCodeSelectionTests SmallSense__CustomSourceCodeSelectionTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomSubContextTests SmallSense__CustomSubContextTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomTestCaseHelper SmallSense__CustomTestCaseHelper stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers' 0
+SmallSense::CustomTestCaseHelperTests SmallSense__CustomTestCaseHelperTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Helpers-Tests' 1
+jn_refactoring_custom jn_refactoring_custom stx:goodies/smallsense/refactoring_custom '* Projects & Packages *' 3
+SmallSense::CustomAccessMethodsCodeGeneratorTests SmallSense__CustomAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomAddClassChangeTests SmallSense__CustomAddClassChangeTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomAddMethodChangeTests SmallSense__CustomAddMethodChangeTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomBrowserChangeManager SmallSense__CustomBrowserChangeManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomBrowserContext SmallSense__CustomBrowserContext stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomBrowserContextTests SmallSense__CustomBrowserContextTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomChangeNotificationAccessMethodsCodeGeneratorTests SmallSense__CustomChangeNotificationAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomChangeNotificationSetterMethodsCodeGeneratorTests SmallSense__CustomChangeNotificationSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomCodeGenerator SmallSense__CustomCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeGeneratorClassGeneratorTests SmallSense__CustomCodeGeneratorClassGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomCodeGeneratorOrRefactoringTests SmallSense__CustomCodeGeneratorOrRefactoringTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomCodeGeneratorTests SmallSense__CustomCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomCodeGeneratorUserPreferencesTests SmallSense__CustomCodeGeneratorUserPreferencesTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomCodeSelectionToResourceTranslationTests SmallSense__CustomCodeSelectionToResourceTranslationTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings-Tests' 1
+SmallSense::CustomDefaultGetterMethodsCodeGeneratorTests SmallSense__CustomDefaultGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomIsAbstractCodeGeneratorTests SmallSense__CustomIsAbstractCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomLazyInitializationAccessMethodsCodeGeneratorTests SmallSense__CustomLazyInitializationAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomLazyInitializationGetterMethodsCodeGeneratorTests SmallSense__CustomLazyInitializationGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomLocalChangeManager SmallSense__CustomLocalChangeManager stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomMultiSetterMethodsCodeGeneratorTests SmallSense__CustomMultiSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomNamespaceTests SmallSense__CustomNamespaceTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomNewClassGeneratorTests SmallSense__CustomNewClassGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomNoneSourceCodeFormatter SmallSense__CustomNoneSourceCodeFormatter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomRBLocalSourceCodeFormatter SmallSense__CustomRBLocalSourceCodeFormatter stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomRefactoring SmallSense__CustomRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomRefactoringClassGeneratorTests SmallSense__CustomRefactoringClassGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomRefactoryBuilderTests SmallSense__CustomRefactoryBuilderTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Tests' 1
+SmallSense::CustomReplaceIfNilWithIfTrueRefactoringTests SmallSense__CustomReplaceIfNilWithIfTrueRefactoringTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings-Tests' 1
+SmallSense::CustomSilentDialog SmallSense__CustomSilentDialog stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomSimpleAccessMethodsCodeGeneratorTests SmallSense__CustomSimpleAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomSimpleGetterMethodsCodeGeneratorTests SmallSense__CustomSimpleGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomSimpleSetterMethodsCodeGeneratorTests SmallSense__CustomSimpleSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomSubContext SmallSense__CustomSubContext stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom' 0
+SmallSense::CustomSubclassResponsibilityCodeGeneratorTests SmallSense__CustomSubclassResponsibilityCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseCodeGeneratorTests SmallSense__CustomTestCaseCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseMethodCodeGeneratorTests SmallSense__CustomTestCaseMethodCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseSetUpCodeGeneratorTests SmallSense__CustomTestCaseSetUpCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomTestCaseTearDownCodeGeneratorTests SmallSense__CustomTestCaseTearDownCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomUpdateTestCaseCategoryRefactoringTests SmallSense__CustomUpdateTestCaseCategoryRefactoringTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings-Tests' 1
+SmallSense::CustomUserDialog SmallSense__CustomUserDialog stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-UI' 0
+SmallSense::CustomValueHolderAccessMethodsCodeGeneratorTests SmallSense__CustomValueHolderAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderGetterMethodsCodeGeneratorTests SmallSense__CustomValueHolderGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomVisitorCodeGeneratorAcceptVisitorTests SmallSense__CustomVisitorCodeGeneratorAcceptVisitorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomVisitorCodeGeneratorTests SmallSense__CustomVisitorCodeGeneratorTests stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators-Tests' 1
+SmallSense::CustomAccessMethodsCodeGenerator SmallSense__CustomAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeSelectionRefactoring SmallSense__CustomCodeSelectionRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomInspectorTabCodeGenerator SmallSense__CustomInspectorTabCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomIsAbstractCodeGenerator SmallSense__CustomIsAbstractCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomNewClassGenerator SmallSense__CustomNewClassGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomReplaceIfNilWithIfTrueRefactoring SmallSense__CustomReplaceIfNilWithIfTrueRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomSubclassResponsibilityCodeGenerator SmallSense__CustomSubclassResponsibilityCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseCodeGenerator SmallSense__CustomTestCaseCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseMethodCodeGenerator SmallSense__CustomTestCaseMethodCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseSetUpCodeGenerator SmallSense__CustomTestCaseSetUpCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomTestCaseTearDownCodeGenerator SmallSense__CustomTestCaseTearDownCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomUpdateTestCaseCategoryRefactoring SmallSense__CustomUpdateTestCaseCategoryRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomVisitorCodeGenerator SmallSense__CustomVisitorCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomChangeNotificationAccessMethodsCodeGenerator SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomChangeNotificationSetterMethodsCodeGenerator SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeGeneratorClassGenerator SmallSense__CustomCodeGeneratorClassGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomCodeSelectionToResourceTranslation SmallSense__CustomCodeSelectionToResourceTranslation stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomDefaultGetterMethodsCodeGenerator SmallSense__CustomDefaultGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomLazyInitializationAccessMethodsCodeGenerator SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomLazyInitializationGetterMethodsCodeGenerator SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomMultiSetterMethodsCodeGenerator SmallSense__CustomMultiSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomPrintCodeSelectionRefactoring SmallSense__CustomPrintCodeSelectionRefactoring stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Refactorings' 0
+SmallSense::CustomRefactoringClassGenerator SmallSense__CustomRefactoringClassGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomSimpleAccessMethodsCodeGenerator SmallSense__CustomSimpleAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomSimpleGetterMethodsCodeGenerator SmallSense__CustomSimpleGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomSimpleSetterMethodsCodeGenerator SmallSense__CustomSimpleSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomUITestCaseCodeGenerator SmallSense__CustomUITestCaseCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomUITestCaseSetUpCodeGenerator SmallSense__CustomUITestCaseSetUpCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderAccessMethodsCodeGenerator SmallSense__CustomValueHolderAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderGetterMethodsCodeGenerator SmallSense__CustomValueHolderGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomVisitorCodeGeneratorAcceptVisitor SmallSense__CustomVisitorCodeGeneratorAcceptVisitor stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
+SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGenerator SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator stx:goodies/smallsense/refactoring_custom 'Interface-Refactoring-Custom-Generators' 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/bc.mak	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,159 @@
+# $Header$
+#
+# DO NOT EDIT
+# automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+#
+# 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=..\..\stx
+INCLUDE_TOP=$(TOP)\..
+
+
+
+!INCLUDE $(TOP)\rules\stdHeader_bc
+
+!INCLUDE Make.spec
+
+LIBNAME=libstx_goodies_smallsense_refactoring_custom
+MODULE_PATH=refactoring_custom
+RESFILES=refactoring_custom.$(RES)
+
+
+
+LOCALINCLUDES= -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers -I$(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser -I$(INCLUDE_TOP)\stx\goodies\smallsense -I$(INCLUDE_TOP)\stx\goodies\sunit -I$(INCLUDE_TOP)\stx\libbasic -I$(INCLUDE_TOP)\stx\libbasic3 -I$(INCLUDE_TOP)\stx\libcomp -I$(INCLUDE_TOP)\stx\libjava -I$(INCLUDE_TOP)\stx\libjava\tools -I$(INCLUDE_TOP)\stx\libjavascript -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 ..\..\stx\libbasic & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\goodies\refactoryBrowser\changes & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\goodies\refactoryBrowser\helpers & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\goodies\refactoryBrowser\parser & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libbasic2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libbasic3 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libcomp & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libui & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libview & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libview2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\goodies\sunit & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libwidg & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\libwidg2 & $(MAKE_BAT) "CFLAGS_LOCAL=$(GLOBALDEFINES) "
+	pushd ..\..\stx\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__CustomChangeManager.$(O) SmallSense__CustomChangeManager.$(H): SmallSense__CustomChangeManager.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomClassQuery.$(O) SmallSense__CustomClassQuery.$(H): SmallSense__CustomClassQuery.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoring.$(O) SmallSense__CustomCodeGeneratorOrRefactoring.$(H): SmallSense__CustomCodeGeneratorOrRefactoring.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomContext.$(O) SmallSense__CustomContext.$(H): SmallSense__CustomContext.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDialog.$(O) SmallSense__CustomDialog.$(H): SmallSense__CustomDialog.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomManager.$(O) SmallSense__CustomManager.$(H): SmallSense__CustomManager.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMenuBuilder.$(O) SmallSense__CustomMenuBuilder.$(H): SmallSense__CustomMenuBuilder.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMock.$(O) SmallSense__CustomMock.$(H): SmallSense__CustomMock.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNamespace.$(O) SmallSense__CustomNamespace.$(H): SmallSense__CustomNamespace.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBNamespace.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomParseTreeRewriter.$(O) SmallSense__CustomParseTreeRewriter.$(H): SmallSense__CustomParseTreeRewriter.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\ParseTreeRewriter.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\ParseTreeSearcher.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\ParseTreeSourceRewriter.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPerspective.$(O) SmallSense__CustomPerspective.$(H): SmallSense__CustomPerspective.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoryBuilder.$(O) SmallSense__CustomRefactoryBuilder.$(H): SmallSense__CustomRefactoryBuilder.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeFormatter.$(O) SmallSense__CustomSourceCodeFormatter.$(H): SmallSense__CustomSourceCodeFormatter.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeGenerator.$(O) SmallSense__CustomSourceCodeGenerator.$(H): SmallSense__CustomSourceCodeGenerator.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\parser\RBProgramNodeVisitor.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\CodeGenerator.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSourceCodeSelection.$(O) SmallSense__CustomSourceCodeSelection.$(H): SmallSense__CustomSourceCodeSelection.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseHelper.$(O) SmallSense__CustomTestCaseHelper.$(H): SmallSense__CustomTestCaseHelper.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)stx_goodies_smallsense_refactoring_custom.$(O) stx_goodies_smallsense_refactoring_custom.$(H): stx_goodies_smallsense_refactoring_custom.st $(INCLUDE_TOP)\stx\libbasic\LibraryDefinition.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProjectDefinition.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserChangeManager.$(O) SmallSense__CustomBrowserChangeManager.$(H): SmallSense__CustomBrowserChangeManager.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomBrowserContext.$(O) SmallSense__CustomBrowserContext.$(H): SmallSense__CustomBrowserContext.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomContext.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGenerator.$(O) SmallSense__CustomCodeGenerator.$(H): SmallSense__CustomCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLocalChangeManager.$(O) SmallSense__CustomLocalChangeManager.$(H): SmallSense__CustomLocalChangeManager.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomChangeManager.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNoneSourceCodeFormatter.$(O) SmallSense__CustomNoneSourceCodeFormatter.$(H): SmallSense__CustomNoneSourceCodeFormatter.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRBLocalSourceCodeFormatter.$(O) SmallSense__CustomRBLocalSourceCodeFormatter.$(H): SmallSense__CustomRBLocalSourceCodeFormatter.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomSourceCodeFormatter.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoring.$(O) SmallSense__CustomRefactoring.$(H): SmallSense__CustomRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSilentDialog.$(O) SmallSense__CustomSilentDialog.$(H): SmallSense__CustomSilentDialog.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubContext.$(O) SmallSense__CustomSubContext.$(H): SmallSense__CustomSubContext.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomContext.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUserDialog.$(O) SmallSense__CustomUserDialog.$(H): SmallSense__CustomUserDialog.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomDialog.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomAccessMethodsCodeGenerator.$(O) SmallSense__CustomAccessMethodsCodeGenerator.$(H): SmallSense__CustomAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionRefactoring.$(O) SmallSense__CustomCodeSelectionRefactoring.$(H): SmallSense__CustomCodeSelectionRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomInspectorTabCodeGenerator.$(O) SmallSense__CustomInspectorTabCodeGenerator.$(H): SmallSense__CustomInspectorTabCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomIsAbstractCodeGenerator.$(O) SmallSense__CustomIsAbstractCodeGenerator.$(H): SmallSense__CustomIsAbstractCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomNewClassGenerator.$(O) SmallSense__CustomNewClassGenerator.$(H): SmallSense__CustomNewClassGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(O) SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.$(H): SmallSense__CustomReplaceIfNilWithIfTrueRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSubclassResponsibilityCodeGenerator.$(O) SmallSense__CustomSubclassResponsibilityCodeGenerator.$(H): SmallSense__CustomSubclassResponsibilityCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseCodeGenerator.$(O) SmallSense__CustomTestCaseCodeGenerator.$(H): SmallSense__CustomTestCaseCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseMethodCodeGenerator.$(O) SmallSense__CustomTestCaseMethodCodeGenerator.$(H): SmallSense__CustomTestCaseMethodCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseSetUpCodeGenerator.$(O) SmallSense__CustomTestCaseSetUpCodeGenerator.$(H): SmallSense__CustomTestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomTestCaseTearDownCodeGenerator.$(O) SmallSense__CustomTestCaseTearDownCodeGenerator.$(H): SmallSense__CustomTestCaseTearDownCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(O) SmallSense__CustomUpdateTestCaseCategoryRefactoring.$(H): SmallSense__CustomUpdateTestCaseCategoryRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGenerator.$(O) SmallSense__CustomVisitorCodeGenerator.$(H): SmallSense__CustomVisitorCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorClassGenerator.$(O) SmallSense__CustomCodeGeneratorClassGenerator.$(H): SmallSense__CustomCodeGeneratorClassGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(O) SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.$(H): SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomCodeSelectionToResourceTranslation.$(O) SmallSense__CustomCodeSelectionToResourceTranslation.$(H): SmallSense__CustomCodeSelectionToResourceTranslation.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(O) SmallSense__CustomDefaultGetterMethodsCodeGenerator.$(H): SmallSense__CustomDefaultGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(O) SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.$(H): SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomMultiSetterMethodsCodeGenerator.$(O) SmallSense__CustomMultiSetterMethodsCodeGenerator.$(H): SmallSense__CustomMultiSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomPrintCodeSelectionRefactoring.$(O) SmallSense__CustomPrintCodeSelectionRefactoring.$(H): SmallSense__CustomPrintCodeSelectionRefactoring.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeSelectionRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomRefactoringClassGenerator.$(O) SmallSense__CustomRefactoringClassGenerator.$(H): SmallSense__CustomRefactoringClassGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomNewClassGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(O) SmallSense__CustomSimpleAccessMethodsCodeGenerator.$(H): SmallSense__CustomSimpleAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleGetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseCodeGenerator.$(O) SmallSense__CustomUITestCaseCodeGenerator.$(H): SmallSense__CustomUITestCaseCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomTestCaseCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomUITestCaseSetUpCodeGenerator.$(O) SmallSense__CustomUITestCaseSetUpCodeGenerator.$(H): SmallSense__CustomUITestCaseSetUpCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomTestCaseSetUpCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(O) SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.$(H): SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(O) SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.$(H): SmallSense__CustomVisitorCodeGeneratorAcceptVisitor.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomVisitorCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(O) SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.$(H): SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator.st $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomAccessMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGenerator.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomCodeGeneratorOrRefactoring.$(H) $(INCLUDE_TOP)\stx\goodies/smallsense/refactoring_custom\SmallSense__CustomSimpleSetterMethodsCodeGenerator.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)extensions.$(O): extensions.st $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\AddClassChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\AddMethodChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\RefactoryChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\changes\RefactoryClassChange.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBAbstractClass.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBClass.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBMetaclass.$(H) $(INCLUDE_TOP)\stx\goodies\refactoryBrowser\helpers\RBMethod.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libtool\SystemBrowser.$(H) $(INCLUDE_TOP)\stx\libtool\Tools__NewSystemBrowser.$(H) $(INCLUDE_TOP)\stx\libview2\ApplicationModel.$(H) $(INCLUDE_TOP)\stx\libview2\Model.$(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_refactoring_custom.$(O): $(HGROOT)\.hg\dirstate
+!ENDIF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/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/refactoring_custom/extensions.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,998 @@
+"{ Package: 'stx:goodies/smallsense/refactoring_custom' }"!
+
+!AddClassChange methodsFor:'private'!
+
+argumensBySelectorPartsFromMessage: aMessageNode
+    "Returns message arguments as dictionary indexed by selector part name.
+    For example: sel01:arg01 sel02:arg02 should be indexed 
+    'sel01:' -> 'arg01',
+    'sel02:' -> 'arg02' "
+    | argumensBySelectorParts selectorParts |
+
+    argumensBySelectorParts := Dictionary new.
+    selectorParts := aMessageNode selectorParts ? #().
+    aMessageNode arguments ? #() keysAndValuesDo: [ :key :argument |
+        | part |
+
+        part := selectorParts at: key ifAbsent: key.
+        part == key ifFalse: [ 
+            "We found appropriate selector part"
+            part := part value asSymbol
+        ].
+        argumensBySelectorParts at: part put: argument.    
+    ].
+
+    ^ argumensBySelectorParts
+
+    "Created: / 16-11-2014 / 14:47:55 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+package
+
+    ^ package
+
+    "Created: / 09-10-2014 / 23:45:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+package: aPackageName
+
+    package := aPackageName
+
+    "Created: / 08-10-2014 / 20:07:05 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+privateInClassName
+    "Returns privateIn class name (when this class is a private class of another class)"
+
+    ^ self objectAttributeAt: #privateInClassName
+
+    "Created: / 16-11-2014 / 14:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddClassChange methodsFor:'accessing'!
+
+privateInClassName:aClassName
+    "see privateInClassName"
+
+    self objectAttributeAt: #privateInClassName put: aClassName
+
+    "Created: / 16-11-2014 / 14:18:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!AddMethodChange methodsFor:'accessing'!
+
+package: aPackageName    
+
+    package := aPackageName
+
+    "Created: / 08-10-2014 / 19:59:34 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+allClassVarNames
+    | variableNames |
+
+    variableNames := self allClassVariableNames.
+
+    variableNames isNil ifTrue: [ 
+        ^ #()
+    ].
+
+    ^ variableNames
+
+    "Created: / 01-06-2014 / 23:40:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 20-09-2014 / 19:26:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+allSuperclassesDo: aBlock
+    | superclass |
+
+    superclass := self superclass.
+
+    superclass notNil ifTrue: [ 
+        superclass withAllSuperclassesDo: aBlock
+    ].
+
+    "Created: / 21-04-2014 / 19:15:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 14:42:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'method accessing'!
+
+compileMethod: anRBMethod
+    "Creates new method for this class with RBClass"
+    | change method newSource |
+
+    newSource := anRBMethod newSource.
+
+    change := model 
+        compile: newSource
+        in: self
+        classified: anRBMethod category.
+
+    change package: anRBMethod package.
+
+    method := anRBMethod deepCopy 
+        source: newSource;
+        category: anRBMethod category;
+        package: anRBMethod package;
+        model: self model;
+        modelClass: self;
+        yourself.
+
+    self addMethod: method.
+
+    ^ change
+
+    "Created: / 10-10-2014 / 11:37:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 13:08:59 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing - classes'!
+
+compilerClass
+    "Answer a class suitable for compiling a source code in 'my' language"
+
+    ^ self realClass isNil ifTrue: [
+        "Return Smalltalk compiler, because we do not have multiple programming
+        support in this class (yet)"
+        self class compilerClass
+    ] ifFalse: [ 
+        self realClass compilerClass
+    ]
+
+    "Created: / 15-11-2014 / 16:58:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+inheritsFrom: aClass
+
+    ^ self isSubclassOf: aClass.
+
+    "Created: / 11-10-2014 / 00:25:29 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+instAndClassMethodsDo:aOneArgBlock
+    "see Behavior >> instAndClassMethodsDo:"
+
+    self theNonMetaclass methodsDo:aOneArgBlock.
+    self theMetaclass methodsDo:aOneArgBlock.
+
+    "Created: / 01-11-2014 / 21:35:48 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+instVarNames
+    "Returns instance variable names - STX compatibility"
+
+    ^ self instanceVariableNames
+
+    "Created: / 29-05-2014 / 23:46:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 24-09-2014 / 20:36:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 30-09-2014 / 19:30:18 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+instVarNames: aCollectionOfStrings 
+    "Set instance variable names - STX compatibility"
+
+    self instanceVariableNames: aCollectionOfStrings
+
+    "Created: / 30-09-2014 / 19:30:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+isAbstract: aBoolean
+    "see isAbstract"
+
+    self theMetaclass isNil ifTrue: [ 
+        self error: 'This class is not defined in the model.'
+    ].
+
+    self theMetaclass objectAttributeAt: #isAbstract put: aBoolean
+
+    "Created: / 14-12-2014 / 16:39:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 14-12-2014 / 18:12:03 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'autoload check'!
+
+isLoaded
+    "Returns true when the class is auto-loaded.
+    see Metaclass >> isLoaded"
+
+    ^ self class isLoaded
+
+    "Created: / 15-11-2014 / 17:11:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+isSubclassOf: aClass
+    "see Behavior >> isSubclassOf: ( same purpose, but for model class )"
+
+    self allSuperclassesDo: [ :superclass |
+        "we are testing name here, because the class 
+        can be from another namespace"
+        ((superclass name) = (aClass name)) ifTrue: [ 
+            ^ true
+        ]
+    ].
+
+    ^ false
+
+    "Created: / 11-10-2014 / 00:16:42 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+methodDictionary
+    "Stub method, returns real class MethodDictionary, although full MethodDictionary
+    implementation would be better here."
+
+    | methodDictionary |
+
+    methodDictionary := MethodDictionary new.
+
+    self realClass notNil ifTrue: [
+        self realClass methodDictionary do: [ :method | 
+            methodDictionary := methodDictionary 
+                at: method selector asSymbol 
+                putOrAppend: (RBMethod 
+                    for: self 
+                    fromMethod: method 
+                    andSelector: method selector asSymbol)
+        ].
+    ].
+
+    removedMethods notNil ifTrue: [
+        removedMethods do: [ :removedMethod | 
+            | method |
+
+            method := methodDictionary at: removedMethod asSymbol ifAbsent: [ nil ].  
+            method notNil ifTrue: [
+                methodDictionary := methodDictionary removeKeyAndCompress: removedMethod asSymbol.
+            ]
+        ]
+    ].
+
+    newMethods notNil ifTrue: [
+        newMethods do: [ :newMethod |
+            methodDictionary := methodDictionary at: newMethod selector asSymbol putOrAppend: newMethod.
+        ]
+    ].
+
+    ^ methodDictionary
+
+    "Created: / 28-09-2014 / 22:57:28 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 14:42:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-05-2015 / 16:07:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+methodsDo:aOneArgBlock
+    "see Behavior >> methodsDo:"
+
+    self methodDictionary do:aOneArgBlock
+
+    "Created: / 02-11-2014 / 09:47:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+nameWithoutPrefix
+    "see ClassDescription >> nameWithoutPrefix"
+
+    ^ (Smalltalk at: #Class) nameWithoutPrefix: name
+
+    "Created: / 03-08-2014 / 23:29:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 20-09-2014 / 19:21:11 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+owningClass
+    "see Behavior >> owningClass"
+
+    ^ self theMetaclass owningClass
+
+    "Created: / 29-11-2014 / 13:17:10 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+owningClass: aClass
+    "Sets the owning class which is actually stored in the metaclass"
+
+    self theMetaclass owningClass: aClass
+
+    "Created: / 29-11-2014 / 13:21:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+owningClassOrYourself
+    "see Behavior >> owningClassOrYourself"
+
+    self owningClass notNil ifTrue:[^ self topOwningClass].
+    ^ self
+
+    "Created: / 29-11-2014 / 13:44:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+package
+    "see Class >> package ( same purpose, but for model class )"
+    | package |
+
+    package := self objectAttributeAt: #package.
+
+    (package isNil and: [ self realClass notNil ]) ifTrue: [ 
+        package := self realClass package.
+    ].
+
+    ^ package
+
+    "Created: / 09-10-2014 / 23:12:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+package: aPackage
+
+    self objectAttributeAt: #package put: aPackage
+
+    "Created: / 09-10-2014 / 23:12:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+privateClassesAt:aClassNameStringOrSymbol
+    "see Class >> privateClassesAt:"
+
+    | myName privateClassName |
+
+    myName := self name.
+    myName isNil ifTrue:[
+        "/ no name - there cannot be a corresponding private class
+        ^ nil
+    ].
+
+    privateClassName := (myName, '::' ,aClassNameStringOrSymbol) asSymbol.
+
+    ^ model classNamed: privateClassName.
+
+    "Created: / 15-11-2014 / 17:15:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 11:49:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+programmingLanguage
+    "Answer a language instance in which is this class programmed"
+
+    ^ self realClass isNil ifTrue: [
+        "Return Smalltalk language, because we do not have multiple programming
+        support in this class (yet)"
+        self class programmingLanguage
+    ] ifFalse: [ 
+        self realClass programmingLanguage
+    ]
+
+    "Created: / 22-12-2014 / 20:43:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+realSharedPoolNames
+    "see Behavior >> realSharedPoolNames"
+
+    ^ #()
+
+    "Created: / 15-11-2014 / 17:19:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 16-11-2014 / 16:37:08 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'method accessing'!
+
+sourceCodeAt: aSelector
+    "see Behavior >> sourceCodeAt:"
+
+    ^ self sourceCodeFor: aSelector
+
+    "Created: / 31-01-2015 / 19:05:19 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+superclassName: aName
+    "Assign superclass by its name"
+
+    self superclass: (self model classNamed: aName asSymbol)
+
+    "Created: / 28-09-2014 / 22:53:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+theMetaclass
+    "alias for theMetaClass - STX compatibility"
+
+    ^ self theMetaClass.
+
+    "Created: / 26-09-2014 / 16:26:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'accessing'!
+
+theNonMetaclass
+    "alias for theNonMetaClass - STX compatibility"
+
+    ^ self theNonMetaClass
+
+    "Created: / 26-09-2014 / 16:36:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+topNameSpace
+    "see ClassDescription >> topNameSpace"
+
+    ^ self model
+
+    "Created: / 15-11-2014 / 17:26:50 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 16-11-2014 / 16:58:00 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'queries'!
+
+topOwningClass
+    "see Behavior >> topOwningClass"
+
+    ^ self theMetaclass topOwningClass
+
+    "Created: / 29-11-2014 / 13:48:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBAbstractClass methodsFor:'enumerating'!
+
+withAllSuperclassesDo:aBlock
+    "evaluate aBlock for the class and all of its superclasses"
+
+    aBlock value:self.
+    self allSuperclassesDo:aBlock
+
+    "Created: / 29-09-2014 / 22:48:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBClass methodsFor:'compiling'!
+
+compile
+    "Updates class definition in the namespace along with code changes"
+    | change newClass |
+
+    change := model defineClass: self definitionString.
+    change package: self package.
+
+    (model respondsTo: #putModelClass:) ifTrue: [
+        model putModelClass: self  
+    ] ifFalse: [ 
+        newClass := model classNamed: self name.
+        newClass package: self package
+    ].
+
+    ^ change
+
+    "Created: / 25-09-2014 / 22:31:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-11-2014 / 00:06:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBClass methodsFor:'accessing'!
+
+theNonMetaClass
+    "alias for theNonMetaclass - squeak compatibility"
+
+    ^ self theNonMetaclass
+
+    "Created: / 26-09-2014 / 16:50:22 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+owningClass
+    "see PrivateMetaclass >> owningClass"
+    | owningClass |
+
+    owningClass := self objectAttributeAt: #owningClass.
+    owningClass isNil ifTrue: [ 
+        self realClass notNil ifTrue: [ 
+            ^ self model classFor: self realClass owningClass
+        ]
+    ].
+
+    ^ owningClass.
+
+    "Created: / 29-11-2014 / 02:20:07 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+owningClass: aClass
+    "see owningClass"
+
+    self 
+        objectAttributeAt: #owningClass 
+        put: (self model classFor: aClass theNonMetaclass)
+
+    "Created: / 29-11-2014 / 02:23:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 29-11-2014 / 13:38:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+theMetaClass
+    "alias for metaclass - sqeak compatibility"
+
+    ^ self metaclass.
+
+    "Created: / 26-09-2014 / 21:32:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'accessing'!
+
+theMetaclass
+    "alias for metaclass - STX compatibility"
+
+    ^ self metaclass.
+
+    "Created: / 26-09-2014 / 21:28:37 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMetaclass methodsFor:'queries'!
+
+topOwningClass
+    "see PrivateMetaclass >> topOwningClass"
+
+    self owningClass isNil ifTrue:[^ nil].
+
+    self owningClass owningClass notNil ifTrue:[
+        ^ self owningClass topOwningClass
+    ].
+    ^ self owningClass
+
+    "Created: / 29-11-2014 / 13:52:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:24:58 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+category: aCategoryName
+    "Sets in which category/protocol does the method belongs within a class"
+
+    self objectAttributeAt: #category put: aCategoryName.
+
+    "Created: / 06-10-2014 / 07:54:57 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+class: aClass
+    "Helper for enabling usage of either real class or RBClass"
+
+    self modelClass: (self model classFor: aClass)
+
+    "Created: / 05-10-2014 / 21:04:44 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 08-11-2014 / 13:26:35 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'compiling'!
+
+compile
+    "Modifies/adds method in the model class."
+
+    ^ self modelClass compileMethod: self
+
+    "Created: / 06-10-2014 / 11:11:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 10-10-2014 / 12:28:06 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+mclass
+    "see Method >> mclass
+    Returns instace of RBClass, RBMetaclass or nil when unknown"
+
+    ^ self modelClass
+
+    "Created: / 27-11-2014 / 23:20:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+methodArgNames
+    "Returns collection of method argument names"
+
+    | methodNode arguments |
+
+    methodNode := RBParser 
+        parseMethod: self source 
+        onError: [ :str :pos | 
+            self error: 'Cannot parse: ', str, ' at pos: ', pos asString 
+        ].    
+
+    "Transform arguments to what Method returns - keep compatibility"
+    arguments := methodNode arguments.
+
+    arguments isEmptyOrNil ifTrue: [ 
+        ^ nil
+    ].
+
+    ^ Array streamContents: [ :s |
+        arguments do: [ :argument |
+            s nextPut: argument name
+        ]  
+    ]
+
+    "Created: / 07-10-2014 / 20:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 25-01-2015 / 15:35:21 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'queries'!
+
+methodDefinitionTemplate
+    "see Method >> methodDefinitionTemplate"
+
+    ^ Method
+        methodDefinitionTemplateForSelector:self selector
+        andArgumentNames:self methodArgNames
+
+    "Created: / 07-10-2014 / 20:18:53 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+model
+
+    ^ self objectAttributeAt: #model
+
+    "Created: / 05-10-2014 / 20:33:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+model: anRBSmalltalk
+
+    self objectAttributeAt: #model put: anRBSmalltalk
+
+    "Created: / 05-10-2014 / 20:32:38 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+newSource
+    "Returns new source code with performed modifications by CodeGenerator
+    ( replace: something with: anotherthing and custom formatting)."
+    | newSource generator |
+
+    newSource := self source.
+    generator := self sourceCodeGenerator.
+    generator notNil ifTrue: [ 
+        generator source: newSource.
+        newSource := generator newSource.
+    ].
+
+    "Fixes test CustomRBMethodTests >> test_compile_with_code_generator
+    when none selector and method is given then parse the selector from new source code"
+    (selector isNil and: [ compiledMethod isNil ] and: [ newSource notNil ]) ifTrue: [ 
+        selector := (Parser parseMethodSpecification: newSource) selector
+    ].
+
+    ^ newSource
+
+    "Created: / 10-10-2014 / 12:23:20 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified (comment): / 10-10-2014 / 15:31:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+package: aPackage
+
+    self objectAttributeAt: #package put: aPackage
+
+    "Created: / 10-10-2014 / 11:12:26 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'compiler interface'!
+
+programmingLanguage
+    "see CompiledCode >> programmingLanguage"
+
+    self method notNil ifTrue: [ 
+        ^ self method programmingLanguage
+    ].
+
+    self mclass notNil ifTrue: [ 
+        ^ self mclass programmingLanguage
+    ].
+
+    "None programming language found, assume Smalltalk as default"
+    ^ SmalltalkLanguage instance
+
+    "Created: / 26-12-2014 / 11:59:24 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+protocol
+    "Returns in which category/protocol does the method belongs within a class"
+
+    ^ self category
+
+    "Created: / 06-10-2014 / 07:46:14 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+protocol: aProtocolName
+    "Sets in which category/protocol does the method belongs within a class"
+
+    self category: aProtocolName.
+
+    "Created: / 06-10-2014 / 07:56:27 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+replace: placeholder with: code
+
+    self sourceCodeGenerator replace: placeholder with: code
+
+    "Created: / 06-10-2014 / 08:58:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'queries'!
+
+sends:selectorSymbol1 or:selectorSymbol2
+    "Returns true, if this method contains a message-send
+     to either selectorSymbol1 or selectorSymbol2.
+     ( non-optimized version of Message>>sends:or: )"
+
+    ^ (self sendsSelector: selectorSymbol1) or: [ self sendsSelector: selectorSymbol2 ]
+
+    "Created: / 04-10-2014 / 00:01:56 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+sourceCodeGenerator
+    "Returns helper tool for method source code manipulation like formatting and search & replace"
+
+    ^ self objectAttributeAt: #sourceCodeGenerator
+
+    "Created: / 06-10-2014 / 08:33:09 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RBMethod methodsFor:'accessing'!
+
+sourceCodeGenerator: aSourceCodeGenerator
+    "Set ... see method sourceCodeGenerator"
+
+    ^ self objectAttributeAt: #sourceCodeGenerator put: aSourceCodeGenerator
+
+    "Created: / 06-10-2014 / 08:37:54 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RefactoryChange methodsFor:'accessing'!
+
+model
+    "Returns reference to RBNamespace for retrieving model classes (RBClass, RBMetaclass)"
+
+    ^ self objectAttributeAt: #model
+
+    "Created: / 08-11-2014 / 14:00:17 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!RefactoryChange methodsFor:'accessing'!
+
+model: aModel
+    "see model"
+
+    self objectAttributeAt: #model put: aModel
+
+    "Created: / 08-11-2014 / 14:00:33 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+classMenuExtensionCustomGenerators:aMenu 
+    <menuextension: #classMenu>
+
+    self customMenuBuilder
+        perspective: SmallSense::CustomPerspective classPerspective;
+        menu: aMenu;
+        submenuLabel: 'Generate - Custom';
+        afterMenuItemLabelled: 'Generate';
+        generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomCodeGenerator ];
+        buildMenu.
+
+    "Created: / 26-08-2014 / 10:21:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:07:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+classMenuExtensionCustomRefactorings: aMenu 
+    <menuextension: #classMenu>
+
+    self customMenuBuilder
+        perspective: SmallSense::CustomPerspective classPerspective;
+        menu: aMenu;
+        submenuLabel: 'Refactor - Custom';
+        afterMenuItemLabelled: 'Generate';
+        generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomRefactoring ];
+        buildMenu.
+
+    "Created: / 08-11-2014 / 21:24:45 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:31 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:16:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+classMenuExtensionNavigateToTestCase: aMenu
+    "Adds menu item to class list window and tries to guess test case class
+    name. If test case class exists then opens a new tab with this class selected."
+    <menuextension: #classMenu>
+
+    | item index |
+
+    item := MenuItem label: (resources string: 'Open Test Case Class') 
+        itemValue: [ 
+            | className testClassName testClass |
+
+            className := self theSingleSelectedClass theNonMetaclass name.
+            testClassName := (className, 'Tests') asSymbol.
+            testClass := environment at: testClassName ifAbsent: [ nil ].
+            testClass isNil ifTrue: [ 
+                | extensionTestClassName |
+
+                "Small hack for my extension test cases"
+                extensionTestClassName := ('SmallSense::Custom', className, 'Tests') asSymbol.
+                testClass := environment at: extensionTestClassName ifAbsent: [ nil ].
+            ].
+
+            testClass notNil ifTrue: [ 
+                self createBuffer; 
+                    switchToClass: testClass;
+                    selectProtocol: #tests
+            ] ifFalse: [
+                | info |
+
+                info := resources string: 'Test Case named %1 not found'.
+                self information: (info bindWith: testClassName)
+            ].                                                         
+        ].
+
+    item enabled: [ self theSingleSelectedClass notNil ].
+
+    index := aMenu indexOfMenuItemForWhich:[:each | each label = 'Generate' ].
+    index ~~ 0 ifTrue:[
+        aMenu addItem:item beforeIndex:index + 1.
+    ] ifFalse:[
+        aMenu addItem:item.
+    ].
+
+    "Created: / 26-12-2014 / 16:54:30 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 27-12-2014 / 19:01:25 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 12-06-2015 / 20:58:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+codeViewMenuExtensionCustomRefactorings:aMenu 
+    <menuextension: #codeViewMenu>
+
+    self customMenuBuilder
+        perspective: SmallSense::CustomPerspective codeViewPerspective;
+        menu: aMenu;
+        submenuLabel: 'Refactor - Custom';
+        afterMenuItemLabelled: 'Refactor';
+        generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomRefactoring ];
+        buildMenu.
+
+    "Created: / 26-08-2014 / 22:44:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:36 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:17:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+customMenuBuilder
+    "Returns initialized instance of CustomMenuBuilder"
+
+    ^ SmallSense::CustomMenuBuilder new
+        navigationState: self navigationState;
+        resources: resources;
+        yourself
+
+    "Created: / 29-12-2014 / 00:04:15 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:06:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+selectorMenuExtensionCustomGenerators:aMenu 
+    <menuextension: #selectorMenuCompareGenerateDebugSlice>
+
+    self customMenuBuilder
+        perspective: SmallSense::CustomPerspective methodPerspective;
+        menu: aMenu;
+        submenuLabel: 'Generate - Custom';
+        afterMenuItemLabelled: 'Generate';
+        generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomCodeGenerator ];
+        buildMenu.
+
+    "Created: / 26-08-2014 / 10:18:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:40 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:17:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+selectorMenuExtensionCustomRefactorings:aMenu 
+    <menuextension: #selectorMenuCompareGenerateDebugSlice>
+
+    self customMenuBuilder
+        perspective: SmallSense::CustomPerspective methodPerspective;
+        menu: aMenu;
+        submenuLabel: 'Refactor - Custom';
+        afterMenuItemLabelled: 'Refactor';
+        generatorOrRefactoringFilter: [ :generatorOrRefactoring | generatorOrRefactoring isCustomRefactoring ];
+        buildMenu.
+
+    "Created: / 24-08-2014 / 15:23:49 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:46 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:18:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!Tools::NewSystemBrowser methodsFor:'menus extensions-custom refactorings'!
+
+variablesMenuExtensionCustomGenerators:aMenu 
+    <menuextension: #variablesMenu>
+
+    self customMenuBuilder
+        perspective: SmallSense::CustomPerspective instanceVariablePerspective;
+        menu: aMenu;
+        submenuLabel: 'Generate - Custom';
+        afterMenuItemLabelled: 'Generate';
+        buildMenu.
+
+    "Created: / 26-08-2014 / 10:21:54 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 04-01-2015 / 15:08:52 / Jakub Nesveda <nesvejak@fit.cvut.cz>"
+    "Modified: / 11-05-2015 / 09:09:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'documentation'!
+
+extensionsVersion_HG
+
+    ^ '$Changeset: <not expanded> $'
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/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/refactoring_custom/libInit.cc	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,97 @@
+/*
+ * $Header$
+ *
+ * DO NOT EDIT
+ * automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+ */
+#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_refactoring_custom_Init() INIT_TEXT_SECTION;
+DLL_EXPORT void _libstx_goodies_smallsense_refactoring_custom_InitDefinition() INIT_TEXT_SECTION;
+#endif
+
+void _libstx_goodies_smallsense_refactoring_custom_InitDefinition(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libstx_goodies_smallsense_refactoring_custom__DFN", _libstx_goodies_smallsense_refactoring_custom_InitDefinition, "stx:goodies/smallsense/refactoring_custom");
+_stx_137goodies_137smallsense_137refactoring_137custom_Init(pass,__pRT__,snd);
+
+__END_PACKAGE__();
+}
+
+void _libstx_goodies_smallsense_refactoring_custom_Init(pass, __pRT__, snd)
+OBJ snd; struct __vmData__ *__pRT__; {
+__BEGIN_PACKAGE2__("libstx_goodies_smallsense_refactoring_custom", _libstx_goodies_smallsense_refactoring_custom_Init, "stx:goodies/smallsense/refactoring_custom");
+_SmallSense__CustomChangeManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomClassQuery_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGeneratorOrRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomContext_Init(pass,__pRT__,snd);
+_SmallSense__CustomDialog_Init(pass,__pRT__,snd);
+_SmallSense__CustomManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomMenuBuilder_Init(pass,__pRT__,snd);
+_SmallSense__CustomMock_Init(pass,__pRT__,snd);
+_SmallSense__CustomNamespace_Init(pass,__pRT__,snd);
+_SmallSense__CustomParseTreeRewriter_Init(pass,__pRT__,snd);
+_SmallSense__CustomPerspective_Init(pass,__pRT__,snd);
+_SmallSense__CustomRefactoryBuilder_Init(pass,__pRT__,snd);
+_SmallSense__CustomSourceCodeFormatter_Init(pass,__pRT__,snd);
+_SmallSense__CustomSourceCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSourceCodeSelection_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseHelper_Init(pass,__pRT__,snd);
+_stx_137goodies_137smallsense_137refactoring_137custom_Init(pass,__pRT__,snd);
+_SmallSense__CustomBrowserChangeManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomBrowserContext_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomLocalChangeManager_Init(pass,__pRT__,snd);
+_SmallSense__CustomNoneSourceCodeFormatter_Init(pass,__pRT__,snd);
+_SmallSense__CustomRBLocalSourceCodeFormatter_Init(pass,__pRT__,snd);
+_SmallSense__CustomRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomSilentDialog_Init(pass,__pRT__,snd);
+_SmallSense__CustomSubContext_Init(pass,__pRT__,snd);
+_SmallSense__CustomUserDialog_Init(pass,__pRT__,snd);
+_SmallSense__CustomAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeSelectionRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomInspectorTabCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomIsAbstractCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomJavaSimpleSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomNewClassGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomReplaceIfNilWithIfTrueRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomSubclassResponsibilityCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseMethodCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseSetUpCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomTestCaseTearDownCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomUpdateTestCaseCategoryRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomVisitorCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomChangeNotificationAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomChangeNotificationSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGeneratorClassGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomCodeSelectionToResourceTranslation_Init(pass,__pRT__,snd);
+_SmallSense__CustomDefaultGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomLazyInitializationAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomLazyInitializationGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomMultiSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomPrintCodeSelectionRefactoring_Init(pass,__pRT__,snd);
+_SmallSense__CustomRefactoringClassGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSimpleAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSimpleGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomSimpleSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomUITestCaseCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomUITestCaseSetUpCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+_SmallSense__CustomVisitorCodeGeneratorAcceptVisitor_Init(pass,__pRT__,snd);
+_SmallSense__CustomJavaScriptSimpleSetterMethodsCodeGenerator_Init(pass,__pRT__,snd);
+
+_stx_137goodies_137smallsense_137refactoring_137custom_extensions_Init(pass,__pRT__,snd);
+__END_PACKAGE__();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/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 ..\..\stx\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/refactoring_custom/refactoring_custom.rc	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,37 @@
+//
+// DO NOT EDIT
+// automagically generated from the projectDefinition: stx_goodies_smallsense_refactoring_custom.
+//
+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", "My Company\0"
+      VALUE "FileDescription", "Class Library (LIB)\0"
+      VALUE "FileVersion", "6.2.32767.32767\0"
+      VALUE "InternalName", "stx:goodies/smallsense/refactoring_custom\0"
+      VALUE "LegalCopyright", "My CopyRight or CopyLeft\0"
+      VALUE "ProductName", "ProductName\0"
+      VALUE "ProductVersion", "6.2.5.0\0"
+      VALUE "ProductDate", "Thu, 19 Feb 2015 06:05: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/refactoring_custom/stx_goodies_smallsense_refactoring_custom.st	Sun Jun 14 09:54:32 2015 +0100
@@ -0,0 +1,377 @@
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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/refactoring_custom' }"
+
+"{ NameSpace: Smalltalk }"
+
+LibraryDefinition subclass:#stx_goodies_smallsense_refactoring_custom
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'* Projects & Packages *'
+!
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'documentation'!
+
+copyright
+"
+A custom code generation and refactoring support for Smalltalk/X
+Copyright (C) 2013-2015 Jakub Nesveda
+Copyright (C) 2013-now  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:
+
+    API for custom code generation and refactoring.
+
+    [author:]
+        Jakub Nesveda <nesvejak@fit.cvut.cz>
+"
+! !
+
+!stx_goodies_smallsense_refactoring_custom 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/changes'    "AddClassChange - extended"
+        #'stx:goodies/refactoryBrowser/helpers'    "RBAbstractClass - extended"
+        #'stx:goodies/refactoryBrowser/parser'    "ParseTreeRewriter - superclass of SmallSense::CustomParseTreeRewriter"
+        #'stx:goodies/sunit'    "TestAsserter - superclass of SmallSense::CustomAccessMethodsCodeGeneratorTests"
+        #'stx:libbasic'    "LibraryDefinition - superclass of stx_goodies_smallsense_refactoring_custom"
+        #'stx:libtool'    "CodeGenerator - superclass of SmallSense::CustomSourceCodeGenerator"
+        #'stx:libview2'    "ApplicationModel - extended"
+    )
+!
+
+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:goodies/smallsense'    "SmallSense::TestCase - referenced by SmallSense::CustomTestCaseCodeGenerator class>>availableInContext:"
+        #'stx:libbasic3'    "Change - referenced by SmallSense::CustomCodeGeneratorOrRefactoringTestCase>>assertSource:sameAs:"
+        #'stx:libcomp'    "Parser - referenced by RBMethod>>newSource"
+        #'stx:libjava'    "JavaClass - referenced by SmallSense::CustomCodeGeneratorOrRefactoringTests>>test_available_for_programming_languages_in_context_filled_with_class_perspective_java"
+        #'stx:libjava/tools'    "JavaCompiler - referenced by SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator>>buildInContext:"
+        #'stx:libjavascript'    "JavaScriptCompiler - referenced by SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests>>setUp"
+        #'stx:libview'    "WindowGroup - referenced by SmallSense::CustomCodeGeneratorOrRefactoring>>executeInContextWithWaitCursor:"
+        #'stx:libwidg'    "DialogBox - referenced by SmallSense::CustomCodeGeneratorOrRefactoringTests>>test_execute_in_context_aborted"
+        #'stx:libwidg2'    "CheckBox - referenced by SmallSense::CustomDialog>>addCheckBoxOn:labeled:"
+    )
+!
+
+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"
+
+    ^ #(
+    )
+
+    "Modified: / 19-02-2015 / 06:04:23 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!stx_goodies_smallsense_refactoring_custom 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::CustomBrowserEnvironmentTests' autoload)
+        #'SmallSense::CustomChangeManager'
+        #'SmallSense::CustomClassQuery'
+        (#'SmallSense::CustomClassQueryTests' autoload)
+        #'SmallSense::CustomCodeGeneratorOrRefactoring'
+        (#'SmallSense::CustomCodeGeneratorOrRefactoringTestCase' autoload)
+        #'SmallSense::CustomContext'
+        (#'SmallSense::CustomContextTests' autoload)
+        #'SmallSense::CustomDialog'
+        (#'SmallSense::CustomLocalChangeManagerTests' autoload)
+        #'SmallSense::CustomManager'
+        (#'SmallSense::CustomManagerTests' autoload)
+        #'SmallSense::CustomMenuBuilder'
+        (#'SmallSense::CustomMenuBuilderTests' autoload)
+        #'SmallSense::CustomMock'
+        (#'SmallSense::CustomMockTests' autoload)
+        #'SmallSense::CustomNamespace'
+        (#'SmallSense::CustomNewSystemBrowserTests' autoload)
+        (#'SmallSense::CustomNoneSourceCodeFormatterTests' autoload)
+        #'SmallSense::CustomParseTreeRewriter'
+        (#'SmallSense::CustomParseTreeRewriterTests' autoload)
+        #'SmallSense::CustomPerspective'
+        (#'SmallSense::CustomPerspectiveTests' autoload)
+        (#'SmallSense::CustomRBAbstractClassTests' autoload)
+        (#'SmallSense::CustomRBClassTests' autoload)
+        (#'SmallSense::CustomRBLocalSourceCodeFormatterTests' autoload)
+        (#'SmallSense::CustomRBMetaclassTests' autoload)
+        (#'SmallSense::CustomRBMethodTests' autoload)
+        #'SmallSense::CustomRefactoryBuilder'
+        (#'SmallSense::CustomRefactoryClassChangeTests' autoload)
+        #'SmallSense::CustomSourceCodeFormatter'
+        #'SmallSense::CustomSourceCodeGenerator'
+        (#'SmallSense::CustomSourceCodeGeneratorTests' autoload)
+        #'SmallSense::CustomSourceCodeSelection'
+        (#'SmallSense::CustomSourceCodeSelectionTests' autoload)
+        (#'SmallSense::CustomSubContextTests' autoload)
+        #'SmallSense::CustomTestCaseHelper'
+        (#'SmallSense::CustomTestCaseHelperTests' autoload)
+        #'stx_goodies_smallsense_refactoring_custom'
+        (#'SmallSense::CustomAccessMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomAddClassChangeTests' autoload)
+        (#'SmallSense::CustomAddMethodChangeTests' autoload)
+        #'SmallSense::CustomBrowserChangeManager'
+        #'SmallSense::CustomBrowserContext'
+        (#'SmallSense::CustomBrowserContextTests' autoload)
+        (#'SmallSense::CustomChangeNotificationAccessMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomChangeNotificationSetterMethodsCodeGeneratorTests' autoload)
+        #'SmallSense::CustomCodeGenerator'
+        (#'SmallSense::CustomCodeGeneratorClassGeneratorTests' autoload)
+        (#'SmallSense::CustomCodeGeneratorOrRefactoringTests' autoload)
+        (#'SmallSense::CustomCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomCodeGeneratorUserPreferencesTests' autoload)
+        (#'SmallSense::CustomCodeSelectionToResourceTranslationTests' autoload)
+        (#'SmallSense::CustomDefaultGetterMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomIsAbstractCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomLazyInitializationAccessMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomLazyInitializationGetterMethodsCodeGeneratorTests' autoload)
+        #'SmallSense::CustomLocalChangeManager'
+        (#'SmallSense::CustomMultiSetterMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomNamespaceTests' autoload)
+        (#'SmallSense::CustomNewClassGeneratorTests' autoload)
+        #'SmallSense::CustomNoneSourceCodeFormatter'
+        #'SmallSense::CustomRBLocalSourceCodeFormatter'
+        #'SmallSense::CustomRefactoring'
+        (#'SmallSense::CustomRefactoringClassGeneratorTests' autoload)
+        (#'SmallSense::CustomRefactoryBuilderTests' autoload)
+        (#'SmallSense::CustomReplaceIfNilWithIfTrueRefactoringTests' autoload)
+        #'SmallSense::CustomSilentDialog'
+        (#'SmallSense::CustomSimpleAccessMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomSimpleGetterMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomSimpleSetterMethodsCodeGeneratorTests' autoload)
+        #'SmallSense::CustomSubContext'
+        (#'SmallSense::CustomSubclassResponsibilityCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomTestCaseCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomTestCaseMethodCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomTestCaseSetUpCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomTestCaseTearDownCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomUpdateTestCaseCategoryRefactoringTests' autoload)
+        #'SmallSense::CustomUserDialog'
+        (#'SmallSense::CustomValueHolderAccessMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomValueHolderGetterMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGeneratorTests' autoload)
+        (#'SmallSense::CustomVisitorCodeGeneratorAcceptVisitorTests' autoload)
+        (#'SmallSense::CustomVisitorCodeGeneratorTests' autoload)
+        #'SmallSense::CustomAccessMethodsCodeGenerator'
+        #'SmallSense::CustomCodeSelectionRefactoring'
+        #'SmallSense::CustomInspectorTabCodeGenerator'
+        #'SmallSense::CustomIsAbstractCodeGenerator'
+        #'SmallSense::CustomJavaSimpleSetterMethodsCodeGenerator'
+        #'SmallSense::CustomNewClassGenerator'
+        #'SmallSense::CustomReplaceIfNilWithIfTrueRefactoring'
+        #'SmallSense::CustomSubclassResponsibilityCodeGenerator'
+        #'SmallSense::CustomTestCaseCodeGenerator'
+        #'SmallSense::CustomTestCaseMethodCodeGenerator'
+        #'SmallSense::CustomTestCaseSetUpCodeGenerator'
+        #'SmallSense::CustomTestCaseTearDownCodeGenerator'
+        #'SmallSense::CustomUpdateTestCaseCategoryRefactoring'
+        #'SmallSense::CustomVisitorCodeGenerator'
+        #'SmallSense::CustomChangeNotificationAccessMethodsCodeGenerator'
+        #'SmallSense::CustomChangeNotificationSetterMethodsCodeGenerator'
+        #'SmallSense::CustomCodeGeneratorClassGenerator'
+        #'SmallSense::CustomCodeGeneratorOrRefactoringTestCaseCodeGenerator'
+        #'SmallSense::CustomCodeSelectionToResourceTranslation'
+        #'SmallSense::CustomDefaultGetterMethodsCodeGenerator'
+        #'SmallSense::CustomLazyInitializationAccessMethodsCodeGenerator'
+        #'SmallSense::CustomLazyInitializationGetterMethodsCodeGenerator'
+        #'SmallSense::CustomMultiSetterMethodsCodeGenerator'
+        #'SmallSense::CustomPrintCodeSelectionRefactoring'
+        #'SmallSense::CustomRefactoringClassGenerator'
+        #'SmallSense::CustomSimpleAccessMethodsCodeGenerator'
+        #'SmallSense::CustomSimpleGetterMethodsCodeGenerator'
+        #'SmallSense::CustomSimpleSetterMethodsCodeGenerator'
+        #'SmallSense::CustomUITestCaseCodeGenerator'
+        #'SmallSense::CustomUITestCaseSetUpCodeGenerator'
+        #'SmallSense::CustomValueHolderAccessMethodsCodeGenerator'
+        #'SmallSense::CustomValueHolderGetterMethodsCodeGenerator'
+        #'SmallSense::CustomValueHolderWithChangeNotificationAccessMethodsCodeGenerator'
+        #'SmallSense::CustomValueHolderWithChangeNotificationGetterMethodsCodeGenerator'
+        #'SmallSense::CustomValueHolderWithChangeNotificationSetterMethodsCodeGenerator'
+        #'SmallSense::CustomVisitorCodeGeneratorAcceptVisitor'
+        #'SmallSense::CustomJavaScriptSimpleSetterMethodsCodeGenerator'
+    )
+!
+
+extensionMethodNames
+    "list class/selector pairs of extensions.
+     A correponding method with real names must be present in my concrete subclasses"
+
+    ^ #(
+        #'Tools::NewSystemBrowser' selectorMenuExtensionCustomRefactorings:
+        #'Tools::NewSystemBrowser' classMenuExtensionCustomGenerators:
+        #'Tools::NewSystemBrowser' codeViewMenuExtensionCustomRefactorings:
+        #'Tools::NewSystemBrowser' selectorMenuExtensionCustomGenerators:
+        #'Tools::NewSystemBrowser' variablesMenuExtensionCustomGenerators:
+        RBAbstractClass allClassVarNames
+        RBAbstractClass allSuperclassesDo:
+        RBAbstractClass instVarNames
+        RBAbstractClass methodDictionary
+        RBAbstractClass nameWithoutPrefix
+        RBAbstractClass superclassName:
+        RBAbstractClass theMetaclass
+        RBAbstractClass theNonMetaclass
+        RBAbstractClass withAllSuperclassesDo:
+        RBClass compile
+        RBClass theNonMetaClass
+        RBMetaclass theMetaClass
+        RBMetaclass theMetaclass
+        RBAbstractClass instVarNames:
+        RBMethod sends:or:
+        RBMethod category:
+        RBMethod class:
+        RBMethod compile
+        RBMethod methodArgNames
+        RBMethod methodDefinitionTemplate
+        RBMethod model
+        RBMethod model:
+        RBMethod protocol
+        RBMethod protocol:
+        RBMethod replace:with:
+        RBMethod sourceCodeGenerator
+        RBMethod sourceCodeGenerator:
+        AddClassChange package
+        AddClassChange package:
+        AddMethodChange package:
+        RBAbstractClass compileMethod:
+        RBAbstractClass package
+        RBAbstractClass package:
+        RBMethod newSource
+        RBMethod package:
+        RBAbstractClass inheritsFrom:
+        RBAbstractClass isSubclassOf:
+        RBAbstractClass instAndClassMethodsDo:
+        RBAbstractClass methodsDo:
+        RefactoryChange model
+        RefactoryChange model:
+        #'Tools::NewSystemBrowser' classMenuExtensionCustomRefactorings:
+        AddClassChange argumensBySelectorPartsFromMessage:
+        AddClassChange privateInClassName
+        AddClassChange privateInClassName:
+        RBAbstractClass compilerClass
+        RBAbstractClass isLoaded
+        RBAbstractClass privateClassesAt:
+        RBAbstractClass realSharedPoolNames
+        RBAbstractClass topNameSpace
+        RBMetaclass owningClass
+        RBMetaclass owningClass:
+        RBMethod mclass
+        RBAbstractClass owningClass
+        RBAbstractClass owningClass:
+        RBAbstractClass owningClassOrYourself
+        RBAbstractClass topOwningClass
+        RBMetaclass topOwningClass
+        RBAbstractClass isAbstract:
+        RBAbstractClass programmingLanguage
+        RBMethod programmingLanguage
+        #'Tools::NewSystemBrowser' classMenuExtensionNavigateToTestCase:
+        #'Tools::NewSystemBrowser' customMenuBuilder
+        RBAbstractClass sourceCodeAt:
+    )
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'description - project information'!
+
+companyName
+    "Return a companyname which will appear in <lib>.rc"
+
+    ^ 'My Company'
+!
+
+description
+    "Return a description string which will appear in vc.def / bc.def"
+
+    ^ 'Class Library'
+!
+
+legalCopyright
+    "Return a copyright string which will appear in <lib>.rc"
+
+    ^ 'Copyright Jakub Nesveda 2013-2015 & Jan Vrany 2013-now'
+
+    "Modified: / 05-05-2015 / 23:56:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+productName
+    "Return a product name which will appear in <lib>.rc"
+
+    ^ 'ProductName'
+! !
+
+!stx_goodies_smallsense_refactoring_custom class methodsFor:'documentation'!
+
+version_HG
+    ^ '$Changeset: <not expanded> $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/refactoring_custom/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 ..\..\stx\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% %*
+
+
+
+