Initial shot of "new" rake-based builder
authorJan Vrany <jan.vrany@fit.cvut.cz>
Sun, 22 May 2016 00:32:07 +0100
changeset 0 f46260ba26b1
child 1 fdbc4b7badf9
Initial shot of "new" rake-based builder Based on SVN https://swing.fit.cvut.cz/svn/stx/goodies/builder/trunk/rake@592
.hgignore
Gemfile
Jenkinsfile.rb
Rakefile
bin/build-share.sh
bin/change-cvsroot.sh
bin/setenv_mingw32.bat
bin/setenv_mingw64.bat
bin/unzip.exe
bin/zip.exe
rakelib/checkout.rake
rakelib/clean.rake
rakelib/compile.rake
rakelib/debug.rake
rakelib/dist-jv.rake
rakelib/dist.rake
rakelib/dsl.rb
rakelib/extensions.rb
rakelib/help.rake
rakelib/info.rake
rakelib/rbspec.rb
rakelib/setup.rake
rakelib/smalltalk-utils.rb
rakelib/support.rb
rakelib/test.rake
rakelib/vcs.rb
specs/baseline.deps.rake
specs/baseline.rbspec
specs/jv-branch.deps.rake
specs/jv.rbspec
specs/reports-libjava.rbspec
specs/reports-misc.rbspec
specs/stx-6.2.2.rbspec
specs/stx-jv.rbspec
specs/to.rbspec
tests/dsl_tests.rb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,6 @@
+syntax: glob
+
+build
+dists
+reports
+.config.rake
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Gemfile	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,3 @@
+source :rubygems
+
+gem 'rake', '0.8.7'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Jenkinsfile.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,268 @@
+#
+# Build script for Jenkins CI Server. It checks out
+# Smalltalk/X rake build files and run the rakefile
+# for project specified either in PROJECT constant
+# or in environment variable.
+# 
+# If TARGET environment variable is specified, then
+# it builds given target, otherwise build target 'all'.
+#
+
+# to run it in debug mode, set JENKINS_BUILD_DEBUG
+# environment variable to 1, example:
+#
+#    export JENKINS_BUILD_DEBUG=1
+#
+# or on Windows:
+#
+#    set JENKINS_BUILD_DEBUG=1
+#
+debug = ENV['JENKINS_BUILD_DEBUG'] != nil
+
+
+require 'logger'
+require 'tmpdir'
+require 'fileutils'
+require 'rbconfig'
+
+logger = Logger.new(STDERR)
+logger.progname = 'build-jenkins.rb'
+
+
+# Dump environment
+puts "Environment variables"
+ENV.each {| key, value | puts "  #{key}=\"#{value}\""}
+puts "---------------------"
+
+class Logger
+  alias :_fatal_ :fatal
+  def fatal(progname = nil, &block)
+    _fatal_(progname, &block)
+    raise Exception.new("FATAL: #{progname}")
+  end
+end
+
+def win32?
+  (RbConfig::CONFIG['host_os'] =~ /linux|solaris/) == nil
+end
+
+if not defined? PROJECT
+  if ENV['PROJECT']
+    PROJECT = ENV['PROJECT']
+  else
+    puts "No project defined!"
+  end
+end
+
+
+WORKSPACE = ENV['WORKSPACE'] || '.'
+SPECS_URL = nil if not defined? SPECS_URL
+BUILD_NUMBER = ENV['BUILD_NUMBER'] || Time.now.strftime("%Y%m%d")
+JOB_NAME = (ENV['JOB_NAME'] || 'interactive').partition('/')[0]
+# URLs
+
+def builder_url()
+  url = '$HeadURL: https://swing.fit.cvut.cz/svn/stx/goodies/builder/trunk/rake/build-jenkins.rb $'
+  start_marker = '$HeadURL: '
+  end_marker = '/build-jenkins.rb $'
+
+  if ((url.start_with? start_marker) and
+    (url.end_with? end_marker))
+    return url[start_marker.size..-(end_marker.size + 1)]
+  else
+    return 'https://swing.fit.cvut.cz/svn/stx/goodies/builder/trunk/rake'
+  end
+end
+
+logger.info "Builder URL: #{builder_url}"
+
+puts "Builder URL: #{builder_url}"
+
+exit_code = 0
+
+# Config
+if ENV['ARCH'] == nil then
+  ARCH='i386'
+else
+  ARCH=ENV['ARCH']
+end
+
+
+
+# Variables
+build_id = "build_#{BUILD_NUMBER}"
+build_name = $build_name = build_id
+
+attic_dir = File.expand_path(File.join(WORKSPACE , ARCH,  'attic'))
+artifacts_dir = File.expand_path(File.join(WORKSPACE , ARCH, 'artifacts'))
+reports_dir = File.expand_path(File.join(WORKSPACE , ARCH, 'reports' , JOB_NAME, BUILD_NUMBER))
+build_dir = File.expand_path(File.join(WORKSPACE, ARCH))
+
+if win32?
+  # There is no unzip and other tools on Windows by default, so
+  # we have to provide our own, sigh
+  support = File.expand_path(File.join(build_dir, 'builder', 'support' , 'win32'))
+  support = support.gsub('/', '\\')
+  ENV['PATH'] = "#{ENV['PATH']};#{support}"
+  logger.debug "environment: PATH=#{ENV['PATH']}"
+end
+
+Signal.trap("TERM") do
+  puts "Terminating (got SIGTERM)"
+  logger.debug "Terminating (got SIGTERM)"
+  if win32? 
+    
+  else 
+  end
+end
+
+
+begin
+  begin
+    if debug
+      logger.debug "Running in debug mode"
+    end
+
+    # Wipe out workspace
+    [ attic_dir, artifacts_dir, reports_dir ].each do | d |
+      if File.exist? d
+        puts "Wiping out #{d}"
+        FileUtils.rm_rf d
+      end
+    end
+
+
+    FileUtils.mkdir_p(build_dir)
+
+    puts "Building in #{build_dir}"
+
+    project_dirs = "../specs"
+    if defined? PROJECT_DIRS then
+      if win32? then
+        project_dirs = "#{project_dirs};#{PROJECT_DIRS}"
+      else
+        project_dirs = "#{project_dirs}:#{PROJECT_DIRS}"
+      end
+    end
+
+    Dir.chdir build_dir do
+      if not system "svn co --force #{builder_url}  builder"
+        raise Exception.new("Checkout of builder failed!")
+      end
+
+      if SPECS_URL
+        if not system "svn co --force #{SPECS_URL} specs"
+          raise Exception.new("Checkout of specs failed!")
+        end
+      end
+      Dir.chdir 'builder' do
+        out = %x[rake -s PROJECT_DIRS=#{project_dirs} ARCH=#{ARCH} PROJECT=#{PROJECT} info:buildname]
+        if $?.exitstatus != 0
+          raise Exception.new("'rake info:buildname' failed!")
+        else
+          build_name = $build_name = out.chop
+        end
+      end
+    end
+
+    # Build the project
+    Dir.chdir File.join(build_dir , 'builder') do
+      TARGET = 'all' if not defined? TARGET
+      if true #not debug
+        # If build directory already exists (incremental build), then do
+        # a checkout/update before firing a build
+        if (File.exist? "build") && (TARGET == 'all')
+          if not system(*%W{rake PROJECT_DIRS=#{project_dirs} ARCH=#{ARCH} PROJECT=#{PROJECT} update --trace})
+            raise Exception.new("'rake update' failed!")
+          end
+        end
+        if not system(*%W{rake PROJECT_DIRS=#{project_dirs} ARCH=#{ARCH} PROJECT=#{PROJECT} #{TARGET} --trace})
+          raise Exception.new("'rake #{TARGET}' failed!")
+        end
+      else
+       FileUtils.mkdir_p "dists"
+       FileUtils.mkdir_p "reports"
+      end
+    end
+
+    puts "Moving artifacts..."
+    FileUtils.mkdir_p artifacts_dir
+    artifacts = [ [ build_dir, 'builder' , 'dists', '*.zip'     ], # dist files
+      [ build_dir, 'builder' , 'dists', '*.tar.bz2' ], # dist files
+      [ build_dir, 'builder' , 'dists', '*.tar.gz'  ], # dist files
+      ]
+    artifacts.each do | artifact_pattern |
+      Dir.glob(File.join(*artifact_pattern)).each do | artifact |
+        if File.file? artifact
+          puts "  ...#{File.basename(artifact)}"
+          FileUtils.mv artifact , artifacts_dir
+        end
+      end
+    end
+
+    puts "Moving reports..."
+
+    build_reports_dir = File.join(build_dir, 'builder' , 'reports')
+    if File.exist? build_reports_dir
+      # The workspace 'reports' dir might exists from previous builds...
+      FileUtils.mkdir_p File.dirname(reports_dir)
+      if (File.exists? reports_dir)
+        FileUtils.mv build_reports_dir , (File.join(reports_dir, '..'))
+      else
+        FileUtils.mv build_reports_dir , reports_dir
+        # Argh, special hack for Covertura plugin that does not allow variables in pathnames...
+        FileUtils.cp((Dir.glob("#{reports_dir}/*Coverage.xml")), "#{reports_dir}/..")
+      end
+    end
+
+    if File.exist? reports_dir
+      puts "Archiving reports..."
+      if (Config::CONFIG['host_os'] =~ /linux|solaris/) != nil
+        #on Linux/Solaris
+        if not system(*%W{tar cjf #{File.join(artifacts_dir , "#{build_name}_reports.tar.bz2")} #{reports_dir}})
+          raise Exception.new("Cannot archive reports (#{artifacts_dir})")
+        end
+      else
+        #on Windows
+        if not system "zip -q -r  \"#{File.join(artifacts_dir , "#{build_name}_reports.zip")}\" \"#{reports_dir}\""
+          raise Exception.new("Cannot archive reports (#{artifacts_dir})")
+        end
+      end
+    end
+
+    puts "BUILD FINISHED IN #{build_dir}"
+
+  rescue Exception => e
+    begin
+      $stderr.puts()
+      $stderr.puts("ERROR OCCURED DURING BUILD!")
+      $stderr.puts()
+
+      $stderr.puts("Message: #{e.message}")
+      $stderr.puts("Backtrace:")
+      e.backtrace.each { | l | $stderr.puts("  #{l}") }
+
+      exit_code = 1
+      if not File.exist? attic_dir
+        FileUtils.mkdir_p attic_dir
+      end
+    rescue Exception => ee
+      $stderr.puts()
+      $stderr.puts("ERROR IN ERROR HANDLER!!!")
+      $stderr.puts()
+      $stderr.puts("Message: #{ee.message}")
+      $stderr.puts("Backtrace:")
+      ee.backtrace.each { | l | $stderr.puts("  #{l}") }
+
+      exit_code = 9
+    end
+  end
+ensure
+  #Nothing to do here!
+end
+
+if exit_code != 0
+  puts "BUILD FAILED IN #{build_dir}"
+end
+
+exit exit_code
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Rakefile	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,29 @@
+# Following 3 lines are required to setup a Smalltalk/X rakefiles
+defined? STX_RAKEFILES or STX_RAKEFILES = ENV['STX_RAKEFILES'] || "."
+$:.push(STX_RAKEFILES)
+
+require 'rakelib/support.rb'
+
+#include Rake::DSL
+
+import 'rakelib/help.rake'
+import 'rakelib/info.rake'
+import 'rakelib/debug.rake'
+import 'rakelib/setup.rake'
+import 'rakelib/checkout.rake'
+import 'rakelib/compile.rake'
+import 'rakelib/test.rake'
+import 'rakelib/dist.rake'
+import 'rakelib/dist-jv.rake'
+import 'rakelib/clean.rake'
+
+desc "Compiles the project (default task)"
+task :'default' => [ :'setup', :'compile' ]
+
+desc "Builds the project (checkout, compile, test, dist)"
+task :'all' => [ :'setup', :'pre', :'checkout', :'compile', :'test', :'lint', :'dist', :'post' ]
+
+task :'pre'
+
+task :'post'                  
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/build-share.sh	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,66 @@
+#!/bin/bash
+
+function error {
+    echo "ERROR: $1"
+    exit 1
+}
+
+if [ -z "$1" ]; then
+   error "No source build tree specified"
+fi
+
+SRCDIR=$1
+
+if [ ! -d "$SRCDIR" ]; then 
+    error "Source directory does not exist: $SRCDIR"
+fi
+
+if [ -z "$2" ]; then
+    DSTDIR=build
+else 
+    DSTDIR=$2
+fi
+
+if [ ! -d "$DSTDIR" ]; then 
+    error "Destination directory does not exist: $DSTDIR"
+fi
+
+pushd "$SRCDIR"
+repos=$(find ./ -name .hg -prune)
+popd
+
+set -e
+
+for repo_store in $repos; do
+    repo=$(dirname $repo_store)
+    if [ -d $DSTDIR/$repo ]; then
+    	if [ -f $DSTDIR/$repo/.hg/sharedpath ]; then
+    	    echo "Repository $repo already exists and shared"
+    	else 
+    		echo "Directory $repo already exists."
+    		echo -n "Move aside and share (y/N/Ctrl-C)? "
+    		read yesOrNo
+    		if [ $yesOrNo == 'y' ]; then
+    			if ! mv $DSTDIR/$repo $DSTDIR/${repo}_$(date +%Y-%M-%d); then
+                    error "Failed to move $DSTDIR/$repo aside to $DSTDIR/${repo}_$(date +%Y-%M-%d)"
+                fi
+    		fi
+    	fi
+    fi
+
+    if [ -d $DSTDIR/$repo ]; then
+    	if [ ! -d $DSTDIR/$repo/.hg/sharedpath ]; then
+            echo "Not sharing $repo - already exists"
+    	fi
+    else 
+        echo "Sharing $repo..."
+	if [ ! -d "$DSTDIR/$(dirname $repo)" ]; then 
+	    mkdir -p "$DSTDIR/$(dirname $repo)"
+	fi
+	hg share -U -B "$SRCDIR/$repo" "$DSTDIR/$repo"
+	repo_rev=$(hg --cwd "$SRCDIR/$repo" log -r . --template "{node}")
+	echo "Updating to $repo_rev"
+	hg --cwd "$DSTDIR/$repo" update -r $repo_rev
+    fi
+    echo 
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/change-cvsroot.sh	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,36 @@
+#!/bin/sh
+#NEWROOT=:pserver:$(id -un)@cvs.bh.exept.de:/cvs/stx
+
+if [ -z "$1" ]; then
+    echo "Common CVS roots:"
+    # Do not show these to other people, these are useless for them
+    # anyway
+    if [ "$USER" = "jv" ]; then
+	echo " :ext:vrany@exeptn:/cvs/stx       "
+	echo
+	echo " :ext:vrany@dialin.exept.de:/cvs/stx           "
+	echo
+    fi
+cat <<EOF
+ :pserver:cvs@cvs.smalltalk-x.de:/cvs/stx
+     (public eXept CVS, synced once a day. Use this if unsure)
+
+ :ext:swing.fit.cvut.cz/var/local/cvs
+     (SWING mirror. Use this if you have shell account
+      on swing.fit.cvut.cz)
+
+EOF
+    echo -n "Enter new CVS root (or Ctrl-C to abort): "
+    read answer
+else
+    answer="$1"
+fi
+
+if [ ! -z "$answer" ]; then
+    echo "$answer" > /tmp/chcvs.$$
+    find . -name CVS -type d -exec cp /tmp/chcvs.$$ {}/Root \;
+    rm /tmp/chcvs.$$
+else
+    echo "Nothing changed"
+    exit 1	
+fi
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/setenv_mingw32.bat	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,4 @@
+set MINGW_DIR=C:\MINGW
+set MINGW=__MINGW32__
+set USEMINGW_ARG=-DUSEMINGW32
+set PATH=%PATH%;%MINGW_DIR%\bin
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/bin/setenv_mingw64.bat	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,4 @@
+set MINGW_DIR=C:\MINGW64
+set MINGW=__MINGW64__
+set USEMINGW_ARG=-DUSEMINGW64
+set PATH=%PATH%;%MINGW_DIR%\bin
Binary file bin/unzip.exe has changed
Binary file bin/zip.exe has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/checkout.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,129 @@
+#desc "Check out the source code from repository"
+#task :'checkout' => [ :'checkout:baseline',
+#                      :'checkout:stc', 
+#                      :'checkout:librun', 
+#                      :'checkout:packages' ]
+#  
+#task :'checkout:baseline' => [ BUILD_DIR ] do
+#  if (!File.exist? BUILD_DIR / '.checkout_baseline.stamp')	
+#    cvs ":ext:#{ENV['USER']}@swing.fit.cvut.cz/var/local/cvs", "stx"
+#    touch BUILD_DIR / '.checkout_baseline.stamp'
+#  end
+#end
+#
+#task :'checkout:stc' => [ BUILD_DIR ] do
+#  svn "svn+ssh://#{ENV['USER']}@192.168.12.2/svn", "stx/stc"
+#end
+#
+#task :'checkout:librun' => [ BUILD_DIR ] do
+#  svn "svn+ssh://#{ENV['USER']}@192.168.12.2/svn", "stx/librun"
+#end
+#
+#task :'checkout:packages' => [ BUILD_DIR ] do
+#  svn "svn+ssh://#{ENV['USER']}@192.168.12.2/svn", "stx/librun"
+#end
+##### STX_RAKEFILES stuff ends here ######
+
+
+desc "Checkout project code from repositories"
+task :'checkout' => :'checkout:all'
+
+namespace :'checkout' do
+
+  task :'all' => [ :'setup', :'pre', :'main', :'post' ]
+  task :'pre'
+  task :'post'
+
+  task :'main' => [ :'buildtools', :'packages' ]
+  
+  task :'packages'
+
+end
+
+desc "Update the code"
+task :'update' => :'update:all'
+
+namespace :'update' do  
+
+  task :'all' => [ :'setup', :'pre', :'main', :'post' ]
+  task :'pre'
+  task :'post'
+
+  task :'main' => [ :'buildtools', :'packages', :'changesets']
+
+  task :'buildtools' => BUILD_DIR
+  task :'packages' => BUILD_DIR
+  
+  directory BUILD_DIR
+
+  task :'changesets' do
+    Rake::StX::ChangeSet.standardChangesetsDo(BUILD_DIR) { | cs |
+      cs.addRakeUpdateInfo()
+    }
+  end
+
+end
+
+
+
+# common tasks and helpers
+task :'checkout-update:setup-tasks' do
+
+  def _checkout_or_update(proc, pkg)
+    case proc.arity
+    when 0
+        proc.call()
+    when 1
+        proc.call(pkg)
+    when 2
+        proc.call(pkg, BUILD_DIR)
+    else
+      error "Invalid checkouter arity (#{proc}, arity #{proc.arity()}"
+    end
+  end
+
+  project.packages_and_application.each do | pkg |
+    doit = true
+    if pkg.nested_package?
+      # do not checkout nor update nested packages
+      doit = false
+      # unless they are not in the same repo as parent package
+      if (pkg.property_defined? :checkout)
+        doit = true
+      elsif (pkg.property_defined? :repository) and (pkg.repository != pkg.parent_package.repository)
+        # doit = true        
+      end 
+      
+    end
+
+    if doit
+      pkg_wc = File.join(BUILD_DIR , pkg.directory)
+      # define checkout task
+      # TODO
+      task :'checkout:packages' => :"checkout:package:#{pkg.name}"
+
+      if pkg.nested_package?
+        task :"checkout:package:#{pkg.name}" => :"checkout:package:#{pkg.parent_package.name}"
+      end
+      
+      task :"checkout:package:#{pkg.name}" => pkg_wc
+      file pkg_wc do
+        _checkout_or_update(pkg.checkout(), pkg)
+      end
+
+
+      
+      # define update task
+      task :'update:packages' => :"update:package:#{pkg.name}"
+      task :"update:package:#{pkg.name}" do
+        if (File.exist? pkg_wc)
+          _checkout_or_update(pkg.update(), pkg)
+        else 
+          _checkout_or_update(pkg.checkout(), pkg)
+        end
+      end    
+    end
+  end
+end
+
+task :'setup:tasks' => 'checkout-update:setup-tasks'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/clean.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,99 @@
+desc "Clean build tree (remove all object files)"
+task :'clean' => :'clean:all'
+
+namespace :'clean' do
+
+  task :'all' => [ :'setup', :'pre', :'main', :'post' ]
+  task :'pre'
+  task :'post'
+
+  task :'main' => [ :'stc' , 'librun' , :'packages' ]
+
+  task :'stc' do
+    chdir BUILD_DIR / 'stx' / 'stc' do
+      make 'clean'
+    end
+  end
+
+  task :'librun' do
+    chdir BUILD_DIR / 'stx' / 'librun' do
+      make 'clean'      
+    end
+  end
+
+  task :'packages'
+
+end
+
+desc "Clobber build tree (remove all object files and .dll/executables)"
+task :'clobber' => :'clobber:all'
+
+namespace :'clobber' do
+
+  task :'all' => [ :'setup', :'pre', :'main', :'post' ]
+  task :'pre'
+  task :'post'
+
+  task :'main' => [ :'stc' , :'librun' , :'include', :'packages' ]
+
+  task :'include' do
+    rm_rf BUILD_DIR / 'stx' / 'include'  
+  end
+
+  task :'stc' do
+    chdir BUILD_DIR / 'stx' / 'stc' do
+      make 'clobber'
+    end
+  end
+
+  task :'librun' do
+    chdir BUILD_DIR / 'stx' / 'librun' do
+      make 'clobber'      
+    end
+  end
+
+  task :'packages'
+
+end
+
+
+
+# common tasks and helpers
+task :'clean-clobber:setup-tasks' do
+  project.packages_and_application.each do | pkg |
+    pkg_wc = File.join(BUILD_DIR , pkg.directory)
+
+    task :'clean:packages' => :"clean:package:#{pkg.name}"
+
+    task :"clean:package:#{pkg.name}" do
+      #if File.exist? pkg_wc then
+        chdir pkg_wc do
+          if unix?
+            make 'clean' if File.exist('Makefile')
+          end
+          if win32?
+            make 'clean' if File.exist("bmake.bat")
+          end
+        end
+      #end
+    end
+
+    task :'clobber:packages' => :"clobber:package:#{pkg.name}"
+
+    task :"clobber:package:#{pkg.name}" do
+      #if File.exist? pkg_wc then
+        chdir pkg_wc do
+          if unix? && ( File.exist? 'Makefile' )
+            make 'clobber'
+          elsif win32? && ( File.exist? 'bc.mak' )
+            make 'clobber'
+          end
+        end
+      #end
+    end
+  end
+end
+
+task :'setup:tasks' => 'clean-clobber:setup-tasks'
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/compile.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,464 @@
+
+desc "Compile project"
+task :'compile' => :'compile:all'
+
+
+STX_TOP_DIR = BUILD_DIR / 'stx'
+STX_CONF_DIR = STX_TOP_DIR / 'configurations'
+STX_RULES_DIR = STX_TOP_DIR / 'rules'
+if win32?
+  STC = STX_TOP_DIR / 'stc' / 'stc.exe'
+  LIBRUN = STX_TOP_DIR / 'librun' / 'objmingw' / 'librun.dll'
+else
+  STC = STX_TOP_DIR / 'stc' / 'stc'
+  LIBRUN = STX_TOP_DIR / 'librun' / 'librun.so'
+end
+
+# Returns true iff this is machine of one of the core developers...
+def core_developer_machine?
+  # JV's box: jv@..., vranyj1@...
+  if (ENV['USER'] == 'jv') or (ENV['USER'] == 'vranyj1')
+    return true
+  end
+  if (ENV['USERNAME'] == 'jv') or (ENV['USERNAME'] == 'vranyj1')
+    return true
+  end 
+  return false
+end
+
+# Return suitable gcc for compilation. For now, GCC 5.x.x produces wrong code,
+# likely because some garbage C generated.
+def gcc()
+  [ 'gcc', 'gcc-4.9', 'gcc-4.8', 'gcc-4.7', 'gcc-4' ].each do | gcc |
+    begin
+      if (%x[#{gcc} --version] =~ /4\.\d\.\d$/) != nil then
+        return gcc
+      end
+    rescue
+      # Do nothing...
+    end
+  end 
+  raise Exception.new("Could not find suitable GCC, please install GCC 4.9 (or 4.8 or 4.7)")
+end
+
+def should_remove_librun_and_stc_sources
+    return ! core_developer_machine?
+end
+
+def make_or_raise_error(args = '')
+  cmd = "#{MAKE} #{args}"
+  if not system cmd
+    raise Exception.new("make failed: #{cmd}");
+  end
+end
+
+def rm_rf_all_in_except(directory, exceptions = [])
+  if File.directory? directory then
+    Dir.foreach(directory) do | each |
+      if each != '.' and each != '..' and not exceptions.include? each
+        rm_rf File.join(directory, each)
+      end
+    end
+  else
+    rm_f directory
+  end
+end
+
+if unix? 
+  STC_BINARY_FILES = [    
+    'cpu_alpha.h',
+    'cpu_arm.h',
+    'cpu_hppa.h',
+    'cpu_i386.h',
+    'cpu_x86_64.h',
+    'cpu_ia64.h',
+    'cpu_mc68k.h',
+    'cpu_mc88k.h',
+    'cpu_mips.h',
+    'cpu_ns32k.h',
+    'cpu_power.h',
+    'cpu_s390.h',
+    'cpu_sparc.h',
+    'cpu_vax.h',
+    'stc.h',
+    'stcIntern.h',
+    'stcVMdata.h',
+    'stcVMoffsets.h',
+    'stxAsmMacros.h',
+    'stxNames.h',
+    'stxOSDefs.h',
+    'stxTypeMacros.h',     
+    'symbols.stc.seed',
+    'version.h',
+    'README',
+
+    #unix specific
+    'stx-config.sh',
+    'linuxIntern.h',
+    'macIntern.h',
+    'makefile',
+    'Makefile',
+    'Make.proto',
+    'stc',
+    'stc.1',    
+  ]
+  LIBRUN_BINARY_FILES1 = [    
+    'libffi-3.2.1',
+    'md5.h',
+    'main.c',
+    'librun.so',
+    'librun.a',
+    'symlist.c',
+    'Make.proto',
+    'Makefile',
+  ]
+  LIBRUN_BINARY_FILES2 = []
+elsif win32?
+  STC_BINARY_FILES = [    
+    'cpu_alpha.h',
+    'cpu_arm.h',
+    'cpu_hppa.h',
+    'cpu_i386.h',
+    'cpu_x86_64.h',
+    'cpu_ia64.h',
+    'cpu_mc68k.h',
+    'cpu_mc88k.h',
+    'cpu_mips.h',
+    'cpu_ns32k.h',
+    'cpu_power.h',
+    'cpu_s390.h',
+    'cpu_sparc.h',
+    'cpu_vax.h',
+    'stc.h',
+    'stcIntern.h',
+    'stcVMdata.h',
+    'stcVMoffsets.h',
+    'stxAsmMacros.h',
+    'stxNames.h',
+    'stxOSDefs.h',
+    'stxTypeMacros.h', 
+    'symbols.stc.seed',
+    'version.h',
+    'README',
+
+    #windows specific
+    'stx-config.bat',
+    'mingwmake.bat',
+    'ntIntern.h',
+    'nt.h',
+    'Make.proto',
+    'stc.exe',
+  ]  
+  LIBRUN_BINARY_FILES1 = [    
+    'libffi-3.2.1',
+    'md5.h',
+    'main.c',
+    'objmingw', 
+    'bc.mak',
+    'mingwmake.bat',
+    'buildDate.h',
+    'genDate.com',
+  ]
+  LIBRUN_BINARY_FILES2 = [
+    'librun.dll',
+    'librun.lib',
+  ]
+else
+  raise Exception.new("Unsupported platform")
+end
+
+def cleanup_stc()  
+  if should_remove_librun_and_stc_sources()
+    puts "Cleaning up stc..."
+    begin
+      rm_rf_all_in_except(STX_TOP_DIR / 'stc', STC_BINARY_FILES)    
+    rescue
+      # When something goes wrong, be safe and remove whole directory
+      rm_rf STX_TOP_DIR / 'stc'
+    end
+  end
+end
+
+def cleanup_librun()
+  if should_remove_librun_and_stc_sources()
+    puts "Cleaning up librun..."
+    begin
+      rm_rf_all_in_except(STX_TOP_DIR / 'librun', LIBRUN_BINARY_FILES1)
+      if win32? then
+        rm_rf_all_in_except(STX_TOP_DIR / 'librun' / 'objmingw', LIBRUN_BINARY_FILES2)
+      end
+    rescue
+      # When something goes wrong, be safe and remove whole directory
+      rm_rf STX_TOP_DIR / 'librun'
+    end      
+  end
+end
+
+# Setup flags for GCC (both, real GCC and MinGW)
+GCC_CFLAGS_OPT = ARCH == 'i386' ? '-O' : ''
+GCC_CFLAGS_DBG = core_developer_machine? ? '-ggdb3' : ''
+GCC_CFLAGS_PIC = win32? ? '' : '-fPIC'
+GCC_CFLAGS = "-pipe -fno-omit-frame-pointer -fno-stack-protector -fwrapv #{GCC_CFLAGS_PIC} #{GCC_CFLAGS_OPT} #{GCC_CFLAGS_DBG}"
+
+
+namespace :'compile' do
+
+  task :'all' => [ :'prereq', :'pre', :'main', :'post' ]
+
+  task :'pre'
+  task :'post'
+
+  task :'prereq' => [ :'setup' ]
+
+  task :'main' => [ 
+        :'config',
+        :'libraries',
+        :'stc',       
+        :'librun',
+        :'application',        
+        :'changesets'
+      ]
+
+  task :'config' => STX_TOP_DIR / 'include'
+
+  task :'changesets' do
+    Rake::StX::ChangeSet.standardChangesetsDo(BUILD_DIR) { | cs |
+      cs.addRakeCompileInfo()
+    }
+  end
+
+
+  directory STX_TOP_DIR / 'include'
+
+  case
+  when linux?
+    task :'config' => [ STX_CONF_DIR / 'vendorConf',
+      STX_CONF_DIR / 'myConf' ,
+      STX_RULES_DIR / 'stdRules_orig' ,
+      STX_RULES_DIR / 'stdRules' ]
+
+    file STX_RULES_DIR / 'stdRules_orig' do
+      mv STX_RULES_DIR / 'stdRules' , STX_RULES_DIR / 'stdRules_orig'
+      chdir STX_RULES_DIR do
+        ln_s 'stdRules_alt_GNU', 'stdRules'
+      end
+    end
+
+    task STX_RULES_DIR / 'stdRules' do
+      if not (File.exist? STX_RULES_DIR / 'stdRules')
+        chdir STX_RULES_DIR do
+          ln_s 'stdRules_alt_GNU', 'stdRules'
+        end
+      end
+    end
+
+    file STX_RULES_DIR / 'stdRules_orig' do
+      mv STX_RULES_DIR / 'stdRules' , STX_RULES_DIR / 'stdRules_orig'
+    end
+
+    file STX_RULES_DIR / 'stdRules' do
+      chdir STX_RULES_DIR do
+        ln_s 'stdRules_alt_GNU', 'stdRules'
+      end
+    end
+
+    task STX_CONF_DIR / 'vendorConf' do
+      cp STX_CONF_DIR / 'linux-elf' / 'COMMON' / 'defines' , STX_CONF_DIR / 'vendorConf'
+    end
+
+    task STX_CONF_DIR / 'myConf' do
+      if amd64? 
+        if ARCH == 'x86_64'
+          cp STX_CONF_DIR / 'linux-elf' / 'x86_64' / 'defines' , STX_CONF_DIR / 'myConf'
+        else
+          cp STX_CONF_DIR / 'linux-elf' / 'amd64_mode32' / 'defines' , STX_CONF_DIR / 'myConf'
+        end
+      else
+        cp STX_CONF_DIR / 'linux-elf' / 'opt-cs-oc' / 'defines' , STX_CONF_DIR / 'myConf'
+      end
+
+      File.open(STX_CONF_DIR / 'myConf', 'a') do | f |
+        f.puts "CC=#{gcc()}"
+
+        if defined? STCCOMMONOPT
+          f.puts "STCCOMMONOPT=#{STCCOMMONOPT}"
+        end
+
+        f.puts "OPT=#{GCC_CFLAGS}"
+        f.puts "LIBRUN_OPT=$(OPT)"
+        f.puts "O_RULE=__STANDARD_O_RULE__"
+        f.puts "EXTRA_LIBS=-ldl -lX11 -lXext"
+        f.puts "XDEFS+=-DHAVE_FONTCONFIG -DXFT"
+        f.puts "XINCLUDE+=$(shell pkg-config --cflags xft)"
+        f.puts "LIB_XFT=-l:libXft.so.2 -l:libfontconfig.so.1"
+        if amd64? and ARCH == 'x86_64' then
+          f.puts 'MAKE_ZLIB_ARG= "CFLAGS=-fPIC -O3 -DUSE_MMAP"'
+          # Hack to build FFI for 64-bit Linux builds
+          f.puts 'FFI_OBJS=$(FFI_DIR)/build/src/*.o $(FFI_DIR)/build/src/x86/*.o'
+          f.puts 'FFI_DIR=libffi-3.0.10rc8'
+          f.puts 'OPTIONAL_HAVE_FFI_ARG=-DHAVE_FFI -I$(TOP)/librun/$(FFI_DIR)/build/include'
+          f.puts 'OPTIONAL_FFI_TARGET_IN_LIBRUN=ffi'
+          f.puts 'FFI_CC="$(CC) -m64 -fPIC"'
+          f.puts 'FFI_LD="ld -m elf_x84_64"'
+        end        
+      end
+    end
+  when win32?
+    task :'config' => [ STX_RULES_DIR / 'stdRules_bc_mingwhack.txt' ]
+
+    file STX_RULES_DIR / 'stdRules_bc_mingwhack.txt' do
+      File.open( STX_RULES_DIR / 'stdRules_bc', 'a') do | f |
+        f.puts "!if defined(USEMINGW32) || defined(USEMINGW64)"
+        f.puts "CFLAGS=#{GCC_CFLAGS} $(CFLAGS1) $(CFLAGS2) $(LOCALINCLUDES) $(CLOCAL_INCL) $(CFLAGS_LOCAL)"
+        f.puts "!endif"
+      end
+      File.open( STX_RULES_DIR / 'stdRules_bc_mingwhack.txt', 'a') do | f |
+        f.puts "stdRules_bc CFLAGS already fixed"
+      end
+    end
+  else
+    error "Unsuported platform: #{Config::CONFIG['host_os']}"
+  end
+
+  rule 'makefile' do | t |
+    if File.exist?(File.dirname(t.name) / 'GNUmakefile')
+  rm (File.dirname(t.name) / 'GNUmakefile')
+    end
+
+    chdir File.dirname(t.name) do
+      sh "'#{STX_TOP_DIR / 'rules' / 'stmkmf'}'"
+    end
+  end
+
+  task :stc do
+    if linux? and amd64? and ARCH == 'i386'
+      stx_make_flags="STC_LEXLIB=libfl/libfl_pic.a"
+    else
+      stx_make_flags=""
+    end
+
+    chdir STX_TOP_DIR / 'stc' do      
+      begin
+        make_or_raise_error stx_make_flags
+        cleanup_stc()
+      rescue Exception => e
+        cleanup_stc()
+        cleanup_librun()
+        error "Cannot compile stx:stc: #{e.description}"
+      end  
+    end
+  
+    if not File.exist? STX_TOP_DIR / 'include' / 'stx-config.h' then
+      cp STX_TOP_DIR / 'stc' / 'stx-config.h' , STX_TOP_DIR / 'include' / 'stx-config.h'
+    end
+
+    if not File.exist? STC
+      cleanup_stc()
+      cleanup_librun()
+      error "Cannot compile stx:stc"
+    end
+  end
+
+ task :librun do
+    chdir STX_TOP_DIR / 'librun' do
+      begin
+        begin
+            if win32_wine?
+              if not File.exist? 'libffi' / 'build_win32' / 'objbc'
+                mkdir 'libffi' / 'build_win32' / 'objbc'
+              end
+            end
+          make_or_raise_error
+          cleanup_librun()
+        rescue Exception => e
+          cleanup_stc()
+          cleanup_librun()
+          error "Cannot compile stx:librun: #{e.description}"
+        end
+      end
+    end
+  end
+
+  if unix?
+    task :stc => STX_TOP_DIR / 'stc' / 'makefile'
+    task :librun => STX_TOP_DIR / 'librun' / 'makefile'
+  end
+
+  if win32? and TOOLCHAIN == 'bcc'
+    directory STX_TOP_DIR / 'lib' / 'bc'
+    task :librun => STX_TOP_DIR / 'lib' / 'bc'
+  end
+
+  task :'libraries'
+
+  if unix?
+    vogl_dir = STX_TOP_DIR / 'support' / 'VGL' / 'vogl'
+
+    task 'libraries' => [ vogl_dir / 'src' / 'libvogl.a' ]
+
+    file vogl_dir / 'src' / 'libvogl.a' => [ vogl_dir / 'makefile'  ] do
+      chdir STX_TOP_DIR / 'support' / 'VGL' / 'vogl' do
+        make
+      end
+    end
+  end
+  
+  if win32? and TOOLCHAIN == 'bcc'
+    libbc = STX_TOP_DIR / 'lib' / 'bc'
+
+    task :'libraries' => [  libbc / 'cs32i.lib' ,
+            libbc / 'stxc32i.lib' ,
+            libbc / 'X11omf.lib' ,
+            libbc / 'Xextomf.lib' ,
+            STX_TOP_DIR / 'support' / 'zlib-1.2.3' / 'objbc' / 'zlib.lib'
+         ]
+
+    file libbc / 'cs32i.lib' => libbc do | t |
+      cp STX_TOP_DIR / 'support' / 'win32' /  'borland' / (File.basename(t.name)), libbc
+    end
+
+    file libbc / 'stxc32i.lib' => libbc do | t |
+    cp STX_TOP_DIR / 'support' / 'win32' /  'borland' / (File.basename(t.name)), libbc
+    end
+
+    file libbc / 'X11omf.lib' => libbc do | t |
+    cp STX_TOP_DIR / 'support' / 'win32' /  'borland' / (File.basename(t.name)), libbc
+    end
+
+
+    file libbc / 'Xextomf.lib' => libbc do | t |
+    cp STX_TOP_DIR / 'support' / 'win32' /  'borland' / (File.basename(t.name)), libbc
+    end
+
+    directory libbc
+
+    file STX_TOP_DIR / 'support' / 'zlib-1.2.3' / 'objbc' / 'zlib.lib' do
+      chdir STX_TOP_DIR / 'support' / 'zlib-1.2.3' do
+        make
+      end
+    end
+
+  end
+
+end
+
+
+if unix?
+    #task :'stx:libview2:pre' => STX_TOP_DIR / 'support' / 'libjpeg-7' / 'libjpeg.a'
+
+    #file STX_TOP_DIR / 'support' / 'libjpeg-7/libjpeg.a' => STX_TOP_DIR / 'support' / 'libjpeg-7' / '.libs' / 'libjpeg.a' do
+    #    cp STX_TOP_DIR / 'support' / 'libjpeg-7' / '.libs' / 'libjpeg.a',
+    #        STX_TOP_DIR / 'support' / 'libjpeg-7' / 'libjpeg.a'
+    #end
+    #
+    #file STX_TOP_DIR / 'support' / 'libjpeg-7' / '.libs' / 'libjpeg.a' do
+    #    chdir STX_TOP_DIR / 'libview2' do
+    #        make '../support/libjpeg-7/.libs/libjpeg.a'
+    #    end
+    #end
+
+end
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/debug.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,13 @@
+# debugging tasks
+
+namespace :'debug' do
+  
+  desc "Runs an IRB in context of build script (for .rbspec debugging)"
+  task :'irb' do
+    require 'irb'
+    IRB.start()
+  end
+end
+##### STX_RAKEFILES stuff ends here ######
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/dist-jv.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,270 @@
+task :'checkout:post' => BUILD_DIR / 'misc' / 'distutils'
+
+file BUILD_DIR / 'misc' / 'distutils'  => BUILD_DIR  do
+  checkout :'swing', 'misc/distutils', :branch => ''
+end
+
+task :'dist:jv' => [ :'dist:jv:pre' , :'dist:jv:main', :'dist:jv:post' ]
+
+  du = BUILD_DIR / 'misc' / 'distutils'
+
+  app_version = nil
+  version = nil
+
+  install_dir = nil
+  bin_dir = nil
+  pkg_dir = nil
+  lib_dir = nil
+  include_dir = nil
+  libexec_dir = nil
+  rc_dir = win32? ? bin_dir : lib_dir
+
+  install_dir_doc = nil
+  doc_dir = nil
+
+
+namespace :'dist:jv' do
+  task :'variables' do
+
+
+    app_name    = project.app_name      || (raise Exception.new("No app_name property specified"))
+    app_version = project.app_version   || (raise Exception.new("No app_version property specified"))
+    version = app_version.split('_').first
+
+    install_dir = DIST_DIR / 'dist' / "#{app_name}-#{app_version}_#{ARCH}-#{PLATFORM}"
+    bin_dir = install_dir / 'bin'
+    pkg_dir = install_dir / 'lib' / 'smalltalkx' / version / 'packages'
+    lib_dir = install_dir / 'lib' / 'smalltalkx' / version / 'lib'
+    include_dir = install_dir / 'lib' / 'smalltalkx' / version / 'include'
+    rc_dir  = win32? ? bin_dir : lib_dir
+    libexec_dir = install_dir / 'lib' / 'smalltalkx' / version / 'bin'
+
+    # install_dir_doc = DIST_DIR / 'docs' / "#{app_name}-#{app_version}_docs"
+    # doc_dir = install_dir_doc / 'share' / 'doc' / 'smalltalkx' / version
+
+    install_dir_doc = install_dir
+    doc_dir = install_dir / 'lib' / 'smalltalkx' / version
+
+
+
+    # HACK to make dirs globally available in 'post' rules...
+    $install_jv_dirs = {
+      :install_dir => install_dir,
+      :bin_dir => bin_dir,
+      :doc_dir => doc_dir,
+      :pkg_dir => pkg_dir,
+      :lib_dir => lib_dir,
+      :include_dir => include_dir,
+      :rc_dir  => rc_dir,
+      :libexec_dir => libexec_dir
+    }
+
+  end
+
+
+
+  desc "Installs jv-branch SDK into #{DIST_DIR}"
+  task :'all' => [:'pre', :'main',:'post', :'archive' ]
+
+  task :'pre'
+  task :'post'
+
+  task :'main' => [ :'setup', :'binaries', :'scripts', :'librun', :'packages', :'resources' , :'doc']
+
+  task :'binaries' => :'variables' do
+    mkdir_p bin_dir
+    mkdir_p libexec_dir
+
+    install STC , bin_dir
+    install STC , libexec_dir
+    case
+    when win32?
+      install BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx.exe', libexec_dir
+      install BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx.com', libexec_dir
+    when unix?
+      install BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx', libexec_dir
+      mv libexec_dir / 'stx' , libexec_dir / 'stx-bin'
+    else
+      error_unsupported_platform
+    end
+  end
+
+  task :'resources' => :'variables' do
+    [
+      'stx/goodies/bitmaps' ,
+      'stx/doc/online/english/credits.html'
+    ].each do | resource |
+      mkdir_p pkg_dir / File.dirname(resource)
+      cp_r   BUILD_DIR / resource , pkg_dir / File.dirname(resource)
+    end
+
+    rm_rf  pkg_dir / 'stx' / 'include'
+    cp_r_dereference  BUILD_DIR / 'stx' / 'include' , include_dir
+  end
+
+  task :'scripts' => :'variables'  do
+    mkdir_p bin_dir
+    mkdir_p lib_dir
+    mkdir_p lib_dir / 'rc.d'
+
+    rc_files = %W{display.rc host.rc keyboard.rc smalltalk_r.rc smalltalk.rc private.rc patches}
+    if win32?
+      rc_files << 'd_win32.rc'
+    else
+      #rc_files << 'd_xfree.rc'
+      #rc_files << 'd_xorg.rc'
+    end
+
+    rc_files.each do | rc_file |
+      install BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / rc_file, rc_dir
+    end
+    install BUILD_DIR / 'stx' / 'projects' / 'smalltalk'/ '*.wsp' , lib_dir
+
+
+    install du / 'src' / 'lib' / 'rc.d' / '*' , lib_dir / 'rc.d'
+    install du / 'src' / 'lib' / '*.rc' , rc_dir
+    if unix?
+      install du / 'src' / 'lib' / "splash-smalltalkx-#{version}.gif", lib_dir / 'splash-smalltalkx.gif'
+    end
+
+    case
+    when win32?
+      install du / 'src-win32' / 'bin' / 'stx.bat' , bin_dir
+    when unix?
+      install du / 'src-unix' / 'bin' / 'stx' , bin_dir
+    else
+      error_unsupported_platform
+    end
+
+  end
+
+  task :'librun' => :'variables'  do
+    case
+    when unix?
+      mkdir_p lib_dir / 'lib'
+      install BUILD_DIR / 'stx' / 'librun' / 'librun.so' , lib_dir / 'lib'
+    when win32?
+      install BUILD_DIR / 'stx' / 'librun' / OBJ_DIR / 'librun.dll', bin_dir
+    else
+      error_unsupported_platform
+    end
+  end
+
+  task :'packages' => :'variables' do
+    mkdir_p lib_dir / 'lib'
+    pkgs = project.packages.clone
+    pkgs.push(project.application)
+    # Sort here by size of package. This forces nested packaged
+    # to be installed after their 'super' package. Fixes
+    # libjava#25
+    pkgs.sort! { | a, b | a.name.size <=> b.name.size }
+
+    pkgs.each do | pkg |
+      rm_rf pkg_dir / pkg.directory if File.exist? pkg_dir / pkg.directory
+      mkdir_p pkg_dir / pkg.directory
+      #cp_rx BUILD_DIR / pkg.directory / '.' , pkg_dir / pkg.directory do | fname |
+      #  /\.svn|CVS|\.cvsignore|objbc|\.H$|\.STH$|\.SC$|\.sc$|\.o/.match(fname) == nil
+      #end
+      install   BUILD_DIR / pkg.directory / '*.st' ,         pkg_dir / pkg.directory
+      install   BUILD_DIR / pkg.directory / 'abbrev.stc' ,   pkg_dir / pkg.directory if File.exist? BUILD_DIR / pkg.directory / 'abbrev.stc'
+      install   BUILD_DIR / pkg.directory / '*.so' ,         pkg_dir / pkg.directory
+      ['resources' , 'bitmaps' , 'styles', 'java' ].each do | subdir |
+        if File.exist? BUILD_DIR / pkg.directory / subdir
+          cp_rx BUILD_DIR / pkg.directory / subdir ,    pkg_dir / pkg.directory do | fname |
+            # fname is full path!!!
+            /\.svn|CVS|\.cvsignore|tests/.match(fname) == nil
+          end
+        end
+      end
+      #Put SVN identification...
+      if File.exist? BUILD_DIR / pkg.directory / '.svn'
+        chdir BUILD_DIR / pkg.directory do
+          sh "svn info > \"#{pkg_dir / pkg.directory / '.svn.info'}\""
+        end
+      end
+
+      if unix?
+        ( pkg_dir / pkg.directory / '**' ).each do | file |
+          chmod 0644, file if File.file? file
+          chmod 0755, file if File.directory? file
+        end
+
+        if not pkg.application?
+          (pkg_dir / pkg.directory / '*.so').each do | dll_name |
+            # make the DLL executable
+            chmod 0777, dll_name
+            # symlink the dll
+            chdir lib_dir / 'lib' do
+              rm File.basename(dll_name) if File.exist? File.basename(dll_name)
+              ln_s File.join('..', '..' , 'packages' , pkg.directory , File.basename(dll_name)) , File.basename(dll_name)
+            end
+          end
+        end
+      end
+
+      if win32?
+        if pkg.application?
+          install BUILD_DIR / pkg.directory / '*.dll', bin_dir
+          install BUILD_DIR / pkg.directory / '*.exe', bin_dir
+          install BUILD_DIR / pkg.directory / '*.com', bin_dir
+          install BUILD_DIR / pkg.directory / 'symbols.stc', bin_dir
+          install BUILD_DIR / pkg.directory / 'modules.stx', bin_dir
+          mv bin_dir / 'stx.exe' , bin_dir / 'stx-bin.exe'
+          mv bin_dir / 'stx.com' , bin_dir / 'stx-bin.com'
+        else
+          rm pkg_dir / pkg.directory / '*.dll'
+        end
+      end
+    end
+  end
+
+  task :'archive' => :'variables' do
+    chdir File.dirname install_dir do
+      if win32?
+  sh *%W{zip -q -r  ..\\#{File.basename(install_dir)}.zip #{File.basename(install_dir)}}
+      else
+  sh *%W{tar cjf ../#{File.basename(install_dir)}.tar.bz2 #{File.basename(install_dir)}}
+      end
+    end
+  end
+
+
+  task :'archive-doc' => :'variables' do
+    if install_dir_doc != pkg_dir then
+      chdir File.dirname install_dir_doc do
+        if win32?
+          sh *%W{zip -q -r  ..\\#{File.basename(install_dir_doc)}.zip #{File.basename(install_dir_doc)}}
+        else
+          sh *%W{tar cjf ../#{File.basename(install_dir_doc)}.tar.bz2 #{File.basename(install_dir_doc)}}
+        end
+      end
+    end
+  end
+
+
+  task :'doc' => :'variables' do
+    mkdir_p doc_dir
+    puts BUILD_DIR / 'stx' / 'doc'
+    cp_rx BUILD_DIR / 'stx' / 'doc' , doc_dir do | fname |
+      # fname is full path!!!
+      /\.svn|CVS|\.cvsignore|books|not_delivered/.match(fname) == nil
+    end
+  end
+end # namespace :'dist:jv'
+
+task :'dist:jv:docs' => [ :'dist:jv:docs:pre' , :'dist:jv:docs:main', :'dist:jv:docs:post' ]
+
+namespace :'dist:jv:docs' do
+  task :'pre'
+  task :'post'
+  task :'main' => [ :'setup', :'files' ]
+
+  task :'setup' => [ :'dist:jv:variables' ]
+
+  task :'files' => :'setup' do
+    raise Exception.new("Not yet implemented");
+  end
+
+end # namespace :'dist:jv:docs'
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/dist.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,91 @@
+require 'rbconfig'
+PLATFORM = win32? ? 'win32' : RbConfig::CONFIG['host_os']
+
+task :'dist' => [ :'compile',
+                  :'dist:pre',
+                  :'dist:main',
+                  :'dist:post' ]
+
+namespace :'dist' do
+  task :'pre'
+  task :'post'
+
+  task :'main'
+
+  directory DIST_DIR
+
+  task :'install-archive' => [ :'setup' , DIST_DIR, :'install' ] do
+    
+    install_dir = BUILD_NAME
+    chdir DIST_DIR do 
+      if win32? 
+        info "Archiving build tree in #{install_dir}.zip"
+        sh "..\\bin\\zip.exe -r  \"#{install_dir}.zip\" #{install_dir}"
+      else
+        info "Archiving build tree in #{install_dir}.tar.bz2"
+        sh *%W{tar cjf #{install_dir}.tar.bz2 #{install_dir}}
+      end
+    end
+    
+  end
+
+  
+  task :'install' => [ :'setup' , DIST_DIR ] do
+    install_dir = DIST_DIR / BUILD_NAME
+    build_dir = BUILD_DIR / project.application.directory    
+    executable = project.application.executable()
+    mkdir_p install_dir
+   
+    if win32?
+      cp build_dir / '*.dll' , install_dir
+      cp build_dir / "#{executable}.exe" , install_dir
+      cp build_dir / 'modules.stx' , install_dir
+      cp build_dir / 'symbols.stc' , install_dir
+    else
+      cp build_dir / '*.so' , install_dir
+      cp build_dir / executable, install_dir
+
+    end
+
+    cp_r build_dir / '*.rc', install_dir
+    cp_rx build_dir / 'resources', install_dir do | fname |
+      /\.hg|\.svn|CVS|\.cvsignore|tests/.match(fname) == nil
+    end
+    # Under Windows, bitmaps go to special directory rather than 
+    # into resources, so we need copy them too...
+
+    if win32? then
+      cp_rx build_dir / 'bitmaps', install_dir do | fname |
+        /\.hg|\.svn|CVS|\.cvsignore|tests/.match(fname) == nil
+      end
+    end
+
+  end
+
+
+  task :'build-tree' => [ :'setup' , DIST_DIR ] do
+             
+    #fname = File.expand_path(DIST_DIR / "#{BUILD_NAME}_build-tree")
+    #error "no archive name" if not fname
+
+    #if (File.expand_path('.') == File.dirname(File.expand_path(DIST_DIR))) 
+    #  dir_to_archive = File.basename(File.expand_path("."))
+    #  dir_where_archive = File.dirname(File.expand_path("."))
+    #else
+    #  dir_to_archive = File.basename(File.expand_path(DIST_DIR))
+    #  dir_where_archive = File.dirname(File.expand_path(DIST_DIR))
+    #end
+
+    #hdir dir_where_archive do 
+    #  if win32? 
+    #    info "Archiving build tree in #{File.basename(fname)}.zip"
+    #    sh "zip -r  \"#{fname}.zip\" *"
+    #  else
+    #    info "Archiving build tree in #{File.basename(fname)}.tar.bz2"
+    #    sh *%W{tar cjf #{fname}.tar.bz2} + Dir.glob('*')
+    #  end
+    #end
+  end
+
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/dsl.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,256 @@
+module Rake
+end
+
+module Rake::StX
+end
+
+class Object
+  def self.new_property_value(*args, &block)
+    if self == Object
+      return args[0]
+    else
+      return self.new(*args, &block)
+    end
+  end
+end
+
+class Proc 
+  def self.new_property_value(*args, &block)
+    # TODO: add check
+    return args[0]
+  end
+end
+
+
+class Fixnum 
+  def self.new_property_value(*args, &block)
+    # TODO: add check
+    return args[0]
+  end
+end
+
+class Symbol
+  def self.new_property_value(*args, &block)
+    # TODO: add check
+    return args[0].to_sym
+  end
+end
+
+
+module Rake::StX::DSL
+
+  # Base class for DSL object that may have properties
+  class Object
+
+    # Class-instance variable to hold property definitions
+    @property_definitions = {} 
+
+    attr_accessor :properties
+        
+    def self.property(name, properties = {})      
+      @property_definitions ||= {}
+      if @property_definitions.include? name
+        raise Exception.new("Property #{name} already defined in class #{self.name}")
+      else
+        prop_def_class = properties[:property_definition_class] || PropertyDefinition
+        @property_definitions[name] = prop_def_class.new(name, self, properties)
+      end
+    end
+
+    def self.property_defined?(name)
+      @property_definitions ||= {}
+      if @property_definitions.include? name
+        return @property_definitions[name]
+      else
+        if self == Rake::StX::DSL::Object
+          return nil
+        else
+          return self.superclass.property_defined?(name)
+        end
+      end
+    end
+
+    def self.property_definition(name)
+      prop_def = self.property_defined?(name)
+      if not prop_def 
+        raise Exception.new("Property #{name} not defined in class #{self.class.name}")
+      end
+      return prop_def
+    end
+
+    def _get_property(name)
+      @properties ||= {}
+      prop = @properties[name]
+      if prop
+        return prop.value
+      else
+        return self.class.property_definition(name).default
+      end
+    end
+
+    def _set_property(name, source = '<unknown source>', *args, &block)
+      @properties ||= {}      
+      prop_def = self.class.property_definition(name)
+      prop = prop_def.instantiate(name, source, @properties[name], args, &block)      
+      @properties[name] = prop     
+    end
+
+    def property_defined?(name)
+      return false if not self.class.property_defined? name
+      return false if @properties == nil
+      return @properties.has_key? name
+    end
+
+
+    def _set_property_value(name, value, source = '<unknown source>')
+      @properties ||= {}      
+      self.class.property_definition(name).validate(value)
+      prop = Property.new(name, value, source, @properties[name])      
+      @properties[name] = prop
+    end
+
+    def clone()
+      c = super()
+      c.properties = {}
+      @properties.each do | name, prop |
+        c.properties[name] = prop.clone()        
+      end
+      return c
+    end
+
+    def merge(other)
+      
+      _merge_properties(other)
+	  return self
+    end
+    
+    def _merge_properties(other)
+      other.properties.each do | name, prop |
+        if not @properties.key? name
+          @properties[name] = prop.clone()
+        end
+      end
+    end
+
+      
+         
+  end # Object
+
+
+  class PropertyDefinition < Object
+
+    attr_accessor :name, :default
+
+    def initialize(name, owning_class, properties = {})
+      @name = name
+      @owning_class = owning_class
+      @values = properties[:values]      
+      @klass = @values ? nil : (properties[:class] || String)
+      @type = properties[:type] || :scalar
+      if properties.include? :default
+        @default = properties[:default]
+      else
+        @default = nil
+      end
+      define_getter()      
+      define_setter()
+    end
+    
+    def default     
+      return @default
+    end
+
+    def valid?(value)
+      #return true
+      if @values 
+        return @values.include? value
+      else
+        return value.kind_of? @klass
+      end
+
+    end
+
+    def validate(value)
+      if not valid? value
+        raise Exception.new("Invalid value (#{value.inspect}) for property :'#{@name}' defined in #{@owning_class.name}")
+      end
+    end
+
+    def instantiate(name, source, previous, args, &block)
+      
+      begin
+        if @values 
+          if not @values.include? args[0]
+            raise Exception.new("Value #{args[0]} not allowed (not one of: #{@values.join(", ")})")
+          else
+            value = args[0]
+          end
+        else
+          value = @klass.new_property_value(*args, &block)
+        end
+        return Property.new(name, value, source, previous)
+      rescue => e
+        puts e.backtrace.join("\n")
+        raise e.exception("Error when instantiating property :'#{name}' in class #{@owning_class.name}: #{e.message}")
+        
+      end
+    end
+
+    def define_getter()
+      name = @name
+      @owning_class.send(:define_method, name) do | *args, &block |        
+        if (args.empty? and not block_given?)
+          return self._get_property(name)
+        else
+          return self._set_property(name, caller()[1], *args, &block)
+        end
+      end
+    end
+
+    def define_setter()
+      name = @name
+      @owning_class.send(:define_method, "#{@name}=") do | value |
+        self._set_property_value(name, value, caller()[1])
+      end
+    end
+    
+  end # PropertyDefinition
+
+  class Property
+    attr_reader :name, :value, :source, :overridden
+    
+
+    def initialize(name, value, source = '<unknown source>' , overridden = nil)
+      @name = name
+      @value = value
+      @source = source || caller(4).first
+      @overridden = overridden
+    end  
+   
+    def clone()
+      if (@value.class == Symbol)
+        value = @value
+      elsif @value.class == NilClass
+        value = nil
+      elsif @value == true || @value == false
+        value = @value
+      else 
+        value = @value.clone
+      end      
+      overriden = @overriden == nil ? nil : @overridden.clone()
+      return self.class.new(@name, value, @source, overridden)      
+    end
+
+  end # class Property
+
+  class PropertyException < Exception    
+  end
+  
+  class PropertyNotFoundException < PropertyException
+  end
+
+  class InvalidPropertyValueException < PropertyException
+  end
+
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/extensions.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,434 @@
+require 'rake'
+require 'rbconfig'
+require 'tsort'
+require 'pathname'
+require 'find'
+
+class String
+  rake_extension("/") do
+    def / (arg)
+      r = File.join(File.expand_path(self), arg.to_s())
+      if arg.to_s.include? ?* or arg.to_s.include? ??
+        r = Dir.glob(r)
+        r.reject! { | f | (f =~ /\.svn|CVS/i) != nil }
+      end
+      return r
+    end
+  end
+end
+
+
+(defined? VERBOSE) || (VERBOSE = nil)
+
+class Object
+  rake_extension("info") do 
+    def info(message, details = nil)
+      if (VERBOSE != nil)
+        $stderr.puts "[INFO] #{message}"
+        if (details) 
+          $stderr.puts "      #{details}"
+        end
+      end
+    end
+  end  
+
+  rake_extension("warn") do 
+    def warn(message, details = nil)
+      if (VERBOSE != nil)
+        $stderr.puts "[WARN] #{message}"
+        if (details) 
+          $stderr.puts "      #{details}"
+        end
+      end
+    end
+  end  
+
+  
+  rake_extension("error") do
+    def error(message)
+      raise Exception.new(message)
+    end
+  end 
+
+
+  rake_extension("error_unsupported_platform") do
+    def error_unsupported_platform()
+      error("Unsupported platform (#{RbConfig::CONFIG['host_os']})")
+    end
+  end 
+
+  
+  rake_extension("win32?") do
+    def win32?      
+      if win32_wine?
+        return true
+      end
+      return (RbConfig::CONFIG['host_os'] =~ /mingw32/) != nil
+    end
+  end 
+
+  rake_extension("win32_wine?") do
+    def win32_wine?      
+      return ENV['CROSSCOMPILE'] == 'wine'
+    end
+  end 
+
+ 
+  rake_extension("unix?") do
+    def unix?     
+      if win32_wine?
+        return false
+      end      
+      return (RbConfig::CONFIG['host_os'] =~ /linux|solaris/) != nil
+    end
+  end 
+    
+  rake_extension("linux?") do
+    def linux?
+      if win32_wine?
+        return false
+      end
+
+      return (RbConfig::CONFIG['host_os'] =~ /linux/i) != nil
+    end
+  end 
+  
+  rake_extension("amd64?") do
+    def amd64?
+      return RbConfig::CONFIG['host_cpu'] == 'x86_64'
+    end
+  end 
+
+  rake_extension("redefine") do
+    def redefine(*args, &block)
+      task_name, arg_names, deps = Rake.application.resolve_args(args)
+      task = Rake.application.lookup(task_name)
+      error "task #{task_name} not defined ant thus cannot be redefined" if not task
+      info "Redefining task #{task.name}"
+      task.clear()
+      task.set_arg_names(arg_names)
+      task.enhance(deps, &block)
+    end
+  end 
+
+  rake_extension("clear") do
+    def clear(*args, &block)
+      if block_given? 
+        error "Block has no meaning when clearing task prereqs"
+      end
+      task_name, arg_names, deps = Rake.application.resolve_args(args)
+      deps = deps.collect { | each | each.to_s }
+      task = Rake.application.lookup(task_name)
+      return nil if not task
+      info "Clearing dependencies of task #{task.name} (#{deps.join(", ")})"
+      task.prerequisites.reject! { | each | deps.include? each.to_s  }    
+      return task
+    end
+  end 
+ 
+  class << self
+    alias :__const_missing__ :const_missing
+  end
+
+  def self.const_missing(name)
+    if ENV[name.to_s]
+      return ENV[name.to_s]
+    else
+      return __const_missing__(name)
+    end
+  end
+end
+
+class Rake::Task
+  class PrerequisiteSorter
+    include TSort
+
+    def initialize(task)
+      @task = task
+    end
+
+   
+    def each_prereq(task)
+      task.prerequisites.each do | prereq |
+        prereq_t = task.application.lookup(prereq, task.scope)
+        if prereq_t
+          yield prereq_t
+        end
+      end
+    end
+
+    def tsort_each_node(&block)
+      each_prereq(@task, &block)      
+    end
+
+    def tsort_each_child(task, &block)      
+      each_prereq(task, &block)      
+    end
+  end # class PrerequisiteSorter
+    
+  def all_prerequisites_sorted
+    return PrerequisiteSorter.new(self).tsort.collect{ | t | t.name }
+  end
+
+end
+
+
+
+module RakeFileUtils
+  
+
+
+  def make(args = '')
+    if win32?
+      #sh "make.exe -N -f bc.mak #{args}"
+      if win32_wine?
+        def make_objdir(directory)              
+          if File.exist? directory / 'bmake.bat'
+            #puts "Making objbc in #{directory}"      
+            if not File.exist?(directory / OBJ_DIR)
+              #puts "Made objbc in #{directory}"      
+              mkdir directory / OBJ_DIR
+            end            
+            Dir.entries(directory).each do | each |              
+              if each != '.' and each != '..' and File.directory?(directory / each)
+                #puts "  recursing into #{directory / each}"
+                make_objdir(directory / each)
+              end
+            end
+          end
+        end
+        make_objdir('.')
+        sh "wine cmd /c #{MAKE} #{args}"
+      else 
+        sh "#{MAKE} #{args}"
+      end
+    else
+      sh "#{MAKE} #{args}"
+    end
+  end
+  
+
+  if false #do not use windows wokkaround
+    alias :__cp__ :cp
+    
+    def cp(src, dst) 
+      src_a = src.to_a
+      if ! win32?
+    return __cp__(src,dst)
+      else
+    # We're on Windoze, sigh...   
+    # The problem here is that sometimes Windoze refuses to copy
+    # the files, ending up with a confusing message:
+    # 'The system cannot find path specified' which actually means
+    # 'the path string is too long' (but still lot shorter than 32k chars...)
+    # Hence this ugly klude, arghhh...
+    
+    # 1 - try to shorten the strings here...
+    wd = Dir.getwd()
+    src_a = src_a.collect do | f | 
+          if f.start_with? wd 
+            f = f.slice(wd.size()+1,f.size())
+          end
+    end
+    if dst.start_with? wd 
+          dst = dst.slice(wd.size()+1,dst.size())
+    end 
+    
+    # 2 - Quote the files names, replace all / with \
+    src_a = src_a.collect { | f | '"' + (f.gsub(File::SEPARATOR, '\\')) + '"' }   
+    dst = '"' + (dst.gsub(File::SEPARATOR, '\\')) + '"'
+    
+    # 3 - try to copy all the files at once:
+    begin
+          cmd = "copy /Y #{src_a.join(' ')} #{dst}"
+          sh cmd
+    rescue Exception => ee 
+          # OK, try to copy then individually...
+          src_a.each do | src |
+            cmd = "copy /Y #{src} #{dst}"     
+            sh cmd
+          end     
+    end
+      end
+    end
+  end
+  
+
+  # Taken from http://www.ruby-forum.com/attachment/4467/filteredCopy.rb
+
+  # Both of these are modified from the implementations
+  # in fileutils.rb from Ruby 1.9.1p378
+
+  # Note that if the filter rejects a subdirectory then everything within that
+  # subdirectory is automatically skipped as well.
+
+  # Like FileUtils.cp_r, but takes a filter proc that can return false to skip a file
+  def cp_rx src, dest, options = {}, &filter
+    fu_check_options options, OPT_TABLE['cp_r']
+    fu_output_message "cp -r#{options[:preserve] ? 'p' : ''}#{options[:remove_destination] ? ' --remove-destination' : ''} #{[src,dest].flatten.join ' '}" if options[:verbose]
+    return if options[:noop]
+    fu_each_src_dest(src, dest) do |s, d|
+        copy_entryx s, d, filter, options[:preserve], options[:dereference_root], options[:remove_destination]
+    end
+  end
+
+  # Like FileUtils.copy_entry, but takes a filter proc that can return false to skip a file
+  def copy_entryx(src, dest, filter, preserve = false, dereference_root = false, remove_destination = false)
+    Entry_.new(src, nil, dereference_root).traverse do |ent|
+        if filter.call(ent.path) then
+          destent = Entry_.new(dest, ent.rel, false)
+          File.unlink destent.path if remove_destination && File.file?(destent.path)
+          ent.copy destent.path
+          ent.copy_metadata destent.path if preserve
+        end
+    end
+  end
+
+  
+  # * ruby implementation of find that follows symbolic directory links
+  # * tested on ruby 1.9.3, ruby 2.0 and jruby on Fedora 20 linux
+  # * you can use Find.prune
+  # * detect symlinks to dirs by path "/" suffix; does nothing with files so `symlink?` method is working fine
+  # * depth first order
+  # * detects cycles and raises an error
+  # * raises on broken links
+  # * uses recursion in the `do_find` proc when directory links are met (takes a lot of nested links until SystemStackError, that's practically never)
+  #
+  # * use like: find_follow(".") {|f| puts f}
+  #
+  # Copyright (c) 2014 Red Hat inc
+  #
+  # Permission is hereby granted, free of charge, to any person obtaining a copy
+  # of this software and associated documentation files (the "Software"), to deal
+  # in the Software without restriction, including without limitation the rights
+  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  # copies of the Software, and to permit persons to whom the Software is
+  # furnished to do so, subject to the following conditions:
+  #
+  # The above copyright notice and this permission notice shall be included in
+  # all copies or substantial portions of the Software.
+  #
+  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  # THE SOFTWARE.
+  def find_follow(*paths)
+    block_given? or return enum_for(__method__, *paths)
+
+    link_cache = {}
+    link_resolve = lambda { |path|
+      # puts "++ link_resolve: #{path}" # trace
+      if link_cache[path]
+        return link_cache[path]
+      else
+        return link_cache[path] = Pathname.new(path).realpath.to_s
+      end
+    }
+    # this lambda should cleanup `link_cache` from unnecessary entries
+    link_cache_reset = lambda { |path|
+      # puts "++ link_cache_reset: #{path}" # trace
+      # puts link_cache.to_s # trace
+      link_cache.select! do |k,v|
+        path == k || k == "/" || path.start_with?(k + "/")
+      end
+      # puts link_cache.to_s # trace
+    }
+    link_is_recursive = lambda { |path|
+      # puts "++ link_is_recursive: #{path}" # trace
+      # the ckeck is useless if path is not a link but not our responsibility
+
+      # we need to check full path for link cycles
+      pn_initial = Pathname.new(path)
+      unless pn_initial.absolute?
+        # can we use `expand_path` here? Any issues with links?
+        pn_initial = Pathname.new(File.join(Dir.pwd, path))
+      end
+
+      # clear unnecessary cache
+      link_cache_reset.call(pn_initial.to_s)
+
+      link_dst = link_resolve.call(pn_initial.to_s)
+
+      pn_initial.ascend do |pn|
+        if pn != pn_initial && link_dst == link_resolve.call(pn.to_s)
+          return {:link => path, :dst => pn}
+        end
+      end
+
+      return false
+    }
+
+    do_find = proc { |path|
+      Find.find(path) do |path|
+        if File.symlink?(path) && File.directory?(File.realpath(path))
+          if path[-1] == "/"
+            # probably hitting https://github.com/jruby/jruby/issues/1895
+            yield(path.dup)
+            Dir.new(path).each { |subpath|
+              do_find.call(path + subpath) unless [".", ".."].include?(subpath)
+            }
+          elsif is_recursive = link_is_recursive.call(path)
+            raise "cannot handle recursive links: #{is_recursive[:link]} => #{is_recursive[:dst]}"
+          else
+            do_find.call(path + "/")
+          end
+        else
+          yield(path)
+        end
+      end
+    }
+
+    while path = paths.shift
+      do_find.call(path)
+    end
+  end  
+
+  # Taken from https://gist.github.com/akostadinov/fc688feba7669a4eb784
+  # based on find_follow.rb : https://gist.github.com/akostadinov/05c2a976dc16ffee9cac
+  # 
+  # * use like: cp_r_dereference 'src', 'dst'
+  #
+  # Note: if directory `src` content is copied instead of the full dir. i.e. you end up
+  #                                     with `dst/*` instead of `dst/basename(src)/*`
+  # 
+  # Copyright (c) 2014 Red Hat inc
+  # 
+  # Permission is hereby granted, free of charge, to any person obtaining a copy
+  # of this software and associated documentation files (the "Software"), to deal
+  # in the Software without restriction, including without limitation the rights
+  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+  # copies of the Software, and to permit persons to whom the Software is
+  # furnished to do so, subject to the following conditions:
+  # 
+  # The above copyright notice and this permission notice shall be included in
+  # all copies or substantial portions of the Software.
+  # 
+  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+  # THE SOFTWARE.
+  
+  # copy recursively dereferencing symlinks
+  def cp_r_dereference(src, dst)
+    src_pn = Pathname.new(src)
+    find_follow(src) do | path |
+      relpath = Pathname.new(path).relative_path_from(src_pn).to_s
+      dstpath = File.join(dst, relpath)
+
+      if File.directory?(path) || ( File.symlink?(path) && File.directory?(File.realpath(path)) )
+        FileUtils.mkdir_p(dstpath)
+      else
+        FileUtils.copy_file(path, dstpath)
+      end
+    end
+  end
+
+end
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/help.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,22 @@
+# Smalltalk/X rakefiles - builtin help
+
+
+task :help do 
+  puts <<HELP
+
+For help on building project, type
+  rake help:project
+
+For any other question, send email to Jan Vrany <jan.vrany@fit.cvut.cz>  
+HELP
+end
+
+task :'help:project' do
+  puts <<HELP
+Building a Smalltalk.X project using rake
+
+HELP
+end
+##### STX_RAKEFILES stuff ends here ######
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/info.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,192 @@
+def _display_tasks(tasks)
+  width = tasks.collect { |t| t.name_with_args.length }.max || 10
+  max_column = Rake.application.truncate_output? ? Rake.application.terminal_width - 'name'.size - width - 7 : nil
+  tasks.each do | t |
+    printf "%-#{width}s  # %s\n",
+    t.name_with_args, max_column ? Rake.application.truncate(t.comment || '', max_column) : t.comment || ''
+  end
+end  
+
+task :'info' do
+  puts "Choose one of the following:"
+  puts 
+  _display_tasks(Rake.application.tasks_in_scope(['info']))   
+end
+
+
+namespace :'info' do
+  desc "Dump environment variables and their values"
+  task :'environment' do
+    puts "Environment variables"
+    ENV.each {| key, value | puts "  #{key}=\"#{value}\""}
+    puts "---------------------"
+  end
+
+  desc "Alias for task into:environment"
+  task :'env' => :'environment'
+  
+
+
+  desc "Dumps variables and their values"
+  task :'variables' do
+    puts "BUILD_DIR = #{BUILD_DIR}"
+  end
+  
+  desc "Show all available tasks"
+  task :'tasks' do
+    puts "All tasks:"
+    puts 
+    Rake.application.tasks.each do | t |
+      puts t.name
+    end
+  end
+
+  namespace :'tasks' do
+
+    desc "Print all tasks that depends on given one"
+    task :'dependents' , :task do | t, args |
+      task_n = args[:task] || (error "No task specified")
+      task =  t.application.lookup(task_n)
+      if not task
+        puts "Task #{task_n} not defined. Forgot to call setup task?"
+      end
+      puts "Tasks that depend on #{task_n}:"
+      t.application.tasks.each do | each_nm |
+        each = t.application[each_nm]
+        if each.prerequisites.include? task_n
+          puts " #{each_nm}"
+        end
+      end
+    end
+
+
+    desc "Print internal state of on given task"
+    task :'inspect' , :task do | t, args |
+      task_n = args[:task] || (error "No task specified")
+      task =  t.application.lookup(task_n)
+      if task 
+        puts task.investigation()      
+        puts "requisited by:"
+        task.application.tasks.each do | each_nm |
+          each = task.application[each_nm]
+          if each.prerequisites.include? task.name
+            puts " #{each_nm}"
+          end
+        end
+        puts
+        puts "actions: "
+        task.actions.each do | a |
+          puts "  #{a}"
+        end
+      else
+        puts "Task #{task_n} not defined. Forgot to call setup task?"
+      end      
+    end
+      
+    desc "Print all prerequisites of given task topologically sorted" 
+    task :'prereq-all' , :task do | t, args |
+      task_n = args[:task] || (error "No task specified")
+      task =  t.application.lookup(task_n)
+      puts "task '#{task_n}'"
+      task.all_prerequisites_sorted.each do | prereq |
+        puts "  => #{prereq} "        
+      end
+    end
+
+
+
+    desc "Show given task and its prerequisites, all tasks if task not specified."
+    task :'prereq' , :task do | t, args |
+      task = args[:task] || nil
+
+      if task
+        tasks = [ t.application.lookup(task) ]
+      else
+        tasks = t.application.tasks
+      end
+
+      puts "task '#{task}'"
+            
+      tasks.each do | t |
+        puts t.name
+        t.prerequisites.each do | prereq |
+          puts "  => #{prereq} "
+        end
+      end
+    end
+  end # namespace :'tasks'
+end
+
+
+
+
+##### STX_RAKEFILES stuff ends here ######
+
+
+
+namespace :'info' do
+
+  desc "Print current platform (win32/linux)"
+  task :'platform' do
+    puts PLATFORM
+  end
+
+  namespace :'project' do
+    
+    desc "Print project name"
+    task :'name' => :'setup:project' do
+      puts project.app_name
+    end
+
+    desc "Print project version"
+    task :'version' => :'setup:project' do
+      puts project.app_version
+    end
+    
+  end
+
+  
+  desc "Print current build name"
+  task :'buildname' => :'setup:project' do
+    puts BUILD_NAME
+  end
+
+  
+
+  task :'tasks' => :'setup:tasks'
+
+  desc "Print info about currently selected project"
+  task :'project' => :'setup:project' do
+    Rake::Stx::Configuration::Printer.new().visit(project())
+  end
+
+  desc "Print project packages in topological order"
+  task :'packages' => 'setup:project' do
+    pkgs_all  = project.packages.collect { | p | p.name }
+    pkgs_all += [ project.application.name ]
+    pkgs_reqd = Rake::Task[project.application.name].all_prerequisites_sorted
+    pkgs_reqd = pkgs_reqd.reject { | p | not pkgs_all.include? p }
+    pkgs_reqd = pkgs_reqd.collect { | p | project.package(p) }
+    pkgs_reqd_and_app = pkgs_reqd + [ project.application ] 
+    puts "project #{project.name} consists of:"
+    pkgs_reqd_and_app.each do | pkg |
+      puts "  #{pkg.name}"
+    end    
+  end
+  
+  desc "List all available projects"
+  task :'projects' => :'setup:projects'  do   
+    puts ""
+    puts "Available projects:"
+    names = projects().values().collect { | prj | String(prj.name) }
+    names.sort!
+    names.each do | nm |
+      puts " - #{nm}"
+    end         
+    puts
+    puts "PROJECT_DIR = \"projects:#{File.join(ENV['HOME'], '.smalltalk' , 'rakefiles' , 'projects')}:#{PROJECT_DIRS}\""
+    puts
+  end
+  
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/rbspec.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,647 @@
+require 'rake'
+require 'tsort'
+require "#{File.dirname(__FILE__)}/dsl"
+
+module Rake
+end
+
+module Rake::DSL
+end
+
+module Rake::Stx  
+end
+
+module Rake::Stx::Configuration
+
+  def self.read_specs_from_dir(dir)
+    if File.exist? dir
+      info "Reading project specs from #{dir}..."
+      d = Dir.new(dir)
+      d.each do | file | 
+        if file[0] != ?. and file =~ /.*\.rbspec$/ 
+          begin
+            info "  #{file}"
+            $:.push(dir)
+            load dir / file            
+          ensure
+            $:.pop()
+          end          
+        end    
+      end
+
+      d.each do | file | 
+        if File.directory? File.join(dir, file)
+          read_specs_from_dir(File.join(dir, file)) if file[0] != ?.
+        end
+      end        
+    end
+  end
+
+  def self.read_specs(project_dirs_spec)
+
+    project_dirs = ['specs' , 
+                    ENV['HOME'] / '.smalltalk' / 'builder'
+                   ]
+
+
+    if win32?
+      project_dirs += project_dirs_spec.split(";")
+    else
+      project_dirs += project_dirs_spec.split(":")
+    end
+    project_dirs.each do | dir |
+      read_specs_from_dir(dir)
+    end
+  end
+
+
+
+  class ConfigurationException < Exception 
+  end
+             
+  class ConfigurationObject < Rake::StX::DSL::Object
+
+    NO_VALUE = Object.new()
+    attr_accessor  :parent
+   attr_reader :last_repository
+
+    
+
+    def initialize(name = nil, parent = nil)
+      @name = name
+      @parent = parent
+      @properties = {}
+    end
+    
+    def name(name = NO_VALUE) 
+      if (name != NO_VALUE)
+        @name = name
+      end
+      return @name
+    end
+
+
+    def group(*properties, &builder)
+      g = Group.new("<group>", self)
+      g._build(properties, &builder)
+      return g
+    end
+    
+    def _build(properties, &builder)
+      if (properties and properties.size() > 0) 
+        properties.last.each do | name, value |        
+          self._set_property(name, caller(4).first, value )
+        end
+      end
+      if (builder != nil)
+        if (builder.arity == -1)
+          self.instance_exec &builder
+        elsif (builder.arity == 0)
+          self.instance_exec &builder          
+        elsif (builder.arity == 1) 
+          self.instance_exec(self,&builder)
+        else
+          raise ConfigurationException.new("invalid arity of builder block (0 or 1 arguments expected, #{builder.arity} given")
+        end
+      end
+    end          
+
+
+    def accept_visitor(visitor)
+      raise Exception.new("Subclass responsibility (#{self.class.name}#accept_visitor")
+    end
+
+  end # class ConfigurationObject
+
+  class Project < ConfigurationObject
+
+    include Rake::DSL
+
+    PROJECTS = {}
+
+    attr_accessor :repositories, :packages, :tasks, :application
+    attr_accessor :last_repository
+
+    def self.named?(name)
+      if (PROJECTS.include?(name)) 
+        p = PROJECTS[name]     
+      else
+        p = nil
+      end
+      return p
+    end
+    
+    def self.named(name)
+      if (PROJECTS.include?(name)) 
+        p = PROJECTS[name]     
+      else
+        p = self.new(name)
+        PROJECTS[name] = p
+      end
+      return p
+    end
+
+    def self.current()
+      if (not defined? @@Current) 
+        @@Current = nil
+      end
+      return @@Current
+    end
+
+    def self.current=(project)
+      @@Current = project
+    end
+
+    property :app_name
+    property :app_version
+    
+    def initialize(name)
+      super(name)
+      @imports = []
+      @repositories = []
+      @packages = []
+      @application = nil
+      @tasks = []
+      @last_repository = nil
+    end
+
+    def clone()
+      p = super()
+      p.repositories = @repositories.clone()
+      p.packages = @packages.clone()
+      return p
+    end
+
+    def packages_and_application()
+      app = self.application()
+      if app 
+        return self.packages() + [ app ]
+      else
+        return self.packages()
+      end
+    end
+
+    class Import
+      def initialize(importee, imported)
+        @importee = importee
+        @imported = imported#as symbol!        
+        @last_repository = importee.last_repository
+      end
+
+      def apply()
+        p = @importee.class.named(@imported)
+        p.apply_imports()
+        @importee.merge(p)
+
+        #merge repositories
+        p.repositories.each do | repo |		  
+		  @importee.repository(repo.name).merge(repo)
+        end
+
+        #merge packages
+        begin
+          importee_last_repository = @importee.last_repository
+          @importee.last_repository = @last_repository
+          p.packages.each do | pkg |
+            if @importee.package? pkg.name
+              @importee.package(pkg.name).merge(pkg)
+            else
+              @importee.packages.push(pkg.clone())
+            end
+            pkg = @importee.package(pkg.name)
+            if (not pkg.repository and @last_repository_name)
+              pkg.set_property(:repository, @last_repository_name)
+            end
+          end
+          app = p.application 
+          if app
+            if @importee.application
+              if @importee.application.parent == @importee
+                @importee.application.merge(app)
+              else
+                @importee.application = app.merge(@importee.application)
+              end
+            else
+              @importee.application = app
+            end
+          end
+        ensure
+          @importee.last_repository = importee_last_repository 
+        end
+            
+        p_tasks = p.tasks.collect { | t | t.clone }
+        @importee.tasks = p_tasks + @importee.tasks
+        info "Importing #{@imported}"
+        info "     into #{@importee.name}"        
+      end
+
+    end # class Import
+
+    def import(name)
+      @imports.push(Import.new(self, name))
+    end
+    
+    def apply_imports() 
+      @imports.each do | import |
+        import.apply()
+      end
+    end
+
+    def repository?(name) 
+      if ((i = @repositories.index { | r | r.name == name }) != nil) 
+        return @repositories[i]
+      else
+        return nil
+      end
+    end
+
+    
+    def repository(name, *properties, &builder)
+      r = repository? name
+      if (r == nil)
+        r = Repository.new(name, self)        
+        @repositories.push(r)
+      end
+      r._build(properties, &builder)
+      @last_repository = r
+      return r
+    end
+
+    def package?(name)
+      if ((i = @packages.index { | r | r.name == name }) != nil) 
+        return @packages[i]        
+      else
+        return nil
+      end
+    end
+
+    def package(name, *properties, &builder)
+      if (not (p = package?(name)))
+        p = Package.new(name, self)
+        @packages.push(p)
+      end      
+      p._build(properties, &builder)
+      if (not p.repository and @last_repository)
+        p.repository = @last_repository.name
+      end
+      return p
+    end
+
+    def application(name = NO_VALUE, *properties, &builder)
+      return @application if name == NO_VALUE         
+      warn "Refefining application for project #{self.name}!" if @application
+      if (not (p = package?(name)))
+        p = Application.new(name, self)
+        @application = p
+      end      
+      p._build(properties, &builder)
+      if (not p.repository and @last_repository)
+        p.repository = @last_repository.name
+      end
+      return p
+    end
+
+    def tasks(*properties, &builder)
+      if (properties.empty? and not builder) 
+        return @tasks
+      else
+        t = Tasks.new()
+        t._build(properties, &builder)
+        @tasks.push(t)
+        return t
+      end
+    end
+
+    def accept_visitor(visitor)
+      return visitor.visit_project(self)
+    end
+
+  end # class Configuration
+
+  class Tasks < ConfigurationObject
+    include Rake::TaskManager    
+
+    def _build(*properties, &builder)
+      super(properties) {} 
+      @builder = builder
+    end
+    
+    def define!()
+      if (@builder != nil)
+        if (@builder.arity == -1)
+          @builder.call()
+        elsif (@builder.arity == 0)
+          @builder.call()
+        elsif (@builder.arity == 1) 
+          @builder.call(self)
+        else
+          raise ConfigurationException.new("invalid arity of builder block (0 or 1 arguments expected, #{builder.arity} given")
+        end
+      end
+    end
+
+    def accept_visitor(visitor)
+      return visitor.visit_tasks(self)
+    end
+
+  end # class Tasks
+
+
+
+  class Package < ConfigurationObject 
+
+    
+    property :repository, :class => Symbol
+    property :branch
+    property :link, :values => [ true, false ], :default => true
+    property :test, :values => [ true, false ], :default => false
+    property :coverage, :values => [ true, false ], :default => false
+    property :lint, :values => [ true, false ], :default => false
+  
+    property :checkout, :default => (Proc.new do | pkg |
+                                     info "Checking out #{pkg.name}..."
+                                     checkout pkg.repository, pkg.directory, 
+                                     :branch => pkg.branch, :package => pkg, :separator => pkg._separator
+                                   end), :class => Proc
+
+    property :update, :default => (Proc.new do | pkg |
+                                   info "Updating #{pkg.name}..."
+                                   update pkg.repository, pkg.directory, 
+                                   :branch => pkg.branch, :package => pkg, :separator => pkg._separator
+                                 end), :class => Proc
+
+    property :stc_flags, :default => '+optinline +optinline2 -optContext', :class => String    
+    
+    def _separator()
+      return (self.parent.repository(self.repository)).separator
+    end
+    
+    def name_components()
+      if not @name_components then
+        @name_components = self.name.sub(":", '/').split('/')
+      end
+      return @name_components
+    end
+
+    def top()
+      # Answers relative path to top directory
+      return File.join(self.name_components().collect { | e | '..' })
+    end
+
+
+    def directory()
+      return File.join(*self.name_components)
+    end
+
+    def dll_name_without_suffix()
+      return "lib#{self.directory.gsub(File::SEPARATOR, "_")}"
+    end
+    
+    def dll_name()
+      case 
+      when win32?
+        return  "#{dll_name_without_suffix()}.dll"
+      when unix?
+        return"#{dll_name_without_suffix()}.so"
+      else
+        error_unsupported_platform
+      end       
+    end
+
+    def nested_package?
+      project.packages.each do | each |
+        if self.name != each.name and self.name.start_with? each.name + '/'
+          return true
+        end
+      end
+      return false
+    end
+
+    def parent_package
+      return nil if not nested_package?
+      last_slash = self.name.rindex(?/)
+      return nil if last_slash == nil
+      parent_package_name = self.name.slice(0, last_slash)
+      project.packages.each do | each |
+        return each if each.name == parent_package_name
+      end
+      return nil
+    end
+
+    def application? 
+      return false
+    end
+
+    def accept_visitor(visitor)
+      return visitor.visit_package(self)
+    end
+    
+  end # class Package
+
+  class Application < Package
+
+    def executable
+      c = self.name_components
+      nm = c.last
+      if win32?
+        #JV@2011-07-22: HACK for Windows, since smalltalk.bat messes the argument list!!!
+        if self.name == 'stx:projects/smalltalk'
+          return 'stx'
+        end        
+      end
+      
+      if nm == 'application' 
+        nm = c[c.size - 2]
+      end
+      return nm
+    end
+
+    def application? 
+      return true
+    end
+
+    def accept_visitor(visitor)
+      return visitor.visit_application(self)
+    end
+
+
+  end # class Application
+
+
+  class Group < ConfigurationObject 
+
+    def initialize(name, parent)
+      super(name, parent)
+      @properties_to_apply = Properties.new('<properties>', self);
+      @nested_entities = []
+    end
+
+    def properties(*properties, &builder)      
+      @properties_to_apply._build(properties, &builder)
+    end
+
+    def _build(*properties, &builder)
+      @properties_to_apply._build(properties)
+      super([], &builder)
+      @nested_entities.each do | each |
+        @properties_to_apply.properties.each do | name, value |
+          each.set_property(name, value, caller(2).first)
+        end
+      end
+    end
+
+    def method_missing(selector, *args, &block)
+      e = parent.send(selector,*args, &block)
+      @nested_entities.push(e)
+      return e
+    end
+    
+    class Properties < ConfigurationObject
+    end # class Group::Properties
+    
+  end # class Group
+  
+  class Repository < ConfigurationObject
+    property :type, :class => Symbol
+    property :url
+    property :separator, :default => '.'
+
+    def accept_visitor(visitor)
+      return visitor.visit_repository(self)
+    end
+
+    
+  end # class Repository
+
+class Visitor
+
+  def visit(object)
+    return object.accept_visitor(self)
+  end
+
+  def visit_project(project)
+    project.repositories.each { | repo | self.visit(repo) }
+    project.packages.each { | repo | self.visit(repo) }
+    project.tasks.each { | repo | self.visit(repo) }
+    self.visit(project.application) if project.application
+  end
+
+  def visit_tasks(tasks)
+    
+  end
+
+  def visit_repository(tasks)
+
+  end
+
+  def visit_package(tasks)
+
+  end
+
+  def visit_application(app)
+    return self.visit_package(app)
+  end
+
+  
+end
+
+class Printer < Visitor 
+
+  attr_accessor :stream
+
+  def print_property(prop, overridden = false)        
+    if overridden
+      puts "#   overrides #{prop.value}"
+      puts "#  defined at #{prop.source}"
+    else
+      puts "#{prop.name} #{prop.value}"
+      puts "# (defined at #{prop.source})"
+    end      
+    print_property(prop.overridden, true) if prop.overridden
+  end
+
+  def print_properties(obj)
+    obj.properties.each do | name, prop |
+      print_property(prop)
+    end
+  end
+
+  def initialize()
+    @indent = 0
+    @stream = $stdout
+  end 
+
+  def puts(*args)
+    args.each do | arg |      
+      @indent.times { | i | @stream.write( "  " )}
+      @stream.puts(arg)
+    end    
+  end
+
+  def indent(increment = 1) 
+    @indent += increment
+    yield
+    @indent -= increment    
+  end
+
+  def visit_repository(repo)
+    puts "repository :'#{repo.name}' do"
+    indent do 
+      print_properties(repo)
+    end
+    puts "end"
+  end
+
+  def visit_package(pkg)
+    puts "#{pkg.application? ? 'application' : 'package'} \"#{pkg.name}\" do"
+    if pkg.nested_package?      
+      puts "  # nested package" 
+      p = pkg.parent_package
+      if p == nil 
+        puts "  # OOPS, parent package not found!"
+      else
+        puts "  # parent package: #{p.name}"
+      end
+    end
+    indent do
+      print_properties(pkg)
+    end
+    puts 'end'
+  end
+
+  def visit_project(project)
+    puts "project :'#{project.name}' do"
+    indent do
+      print_properties(project)
+      super(project)
+    end
+    puts "end"
+  end
+  
+end
+
+  
+end # module Rake::StX::Configuration
+
+def projects()
+  return Rake::Stx::Configuration::Project::PROJECTS
+end
+
+def project(name = Rake::Stx::Configuration::ConfigurationObject::NO_VALUE, *properties, &builder)
+  if (name == Rake::Stx::Configuration::ConfigurationObject::NO_VALUE)
+    return Rake::Stx::Configuration::Project.current()
+  else
+    p = Rake::Stx::Configuration::Project.named(name)
+    p._build(properties, &builder)
+    return p
+  end
+end
+
+def project!(name) 
+  if (p = Rake::Stx::Configuration::Project.named?(name))
+    Rake::Stx::Configuration::Project.current = p
+    return p
+  else
+    raise Rake::Stx::Configuration::ConfigurationException.new("No such project (#{name})")
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/setup.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,320 @@
+
+defined? BUILD_DIR or BUILD_DIR = 'build'
+defined? DIST_DIR or DIST_DIR = 'dists'
+defined? REPORT_DIR or REPORT_DIR = 'reports'
+defined? DEBUG or DEBUG = nil
+
+if win32?
+  ENV['CVS_RSH'] = 'plink' if not ENV['CVS_RSH']
+  ENV['BCB'] = 'C:\\Borland\\BCC55' if not ENV['BCB']
+end
+
+if File.exist? '.config.rake'
+  load '.config.rake'
+else
+  if defined? PROJECT
+    File.open('.config.rake', 'w') do | f |
+      f.puts "PROJECT='#{PROJECT}' if not defined? PROJECT"
+      if defined? PROJECT_DIRS
+      	f.puts "PROJECT_DIRS='#{PROJECT_DIRS}' if not defined? PROJECT_DIRS"
+      end
+    end
+  end
+end
+
+defined? ARCH or ARCH = 'i386'
+
+if not defined? TOOLCHAIN then
+  if unix? then
+    TOOLCHAIN='gcc'
+  elsif win32? then
+    if ARCH=='x86_64' then
+      TOOLCHAIN='mingw64'
+    else
+      # TOOLCHAIN='bcc'
+      TOOLCHAIN="mingw32"
+    end
+  else
+    raise new Exception("Unsupported operating system")    
+  end
+end
+
+defined? PROJECT_DIRS or PROJECT_DIRS = ''
+
+# URLs
+script_url_keyword = '$HeadURL: https://swing.fit.cvut.cz/svn/stx/goodies/builder/trunk/rake/rakelib/setup.rake $'
+
+if ((script_url_keyword.start_with? '$HeadURL: ') and
+    (script_url_keyword.start_with? 'rakelib/setup.rake $'))
+  BUILDER_RAKE_URL = script_url_keyword[('HeadURL: '.size+1)..(script_url_keyword - 'rakelib/setup.rake '.size - 1)]
+else
+  BUILDER_RAKE_URL = 'https://swing.fit.cvut.cz/svn/stx/goodies/builder/trunk/rake'
+end
+
+if TOOLCHAIN == 'gcc' then
+  OBJ_DIR = '.'
+  OBJ_SUFFIX = 'o'
+  MAKE='make'
+elsif TOOLCHAIN == 'bcc' then
+  OBJ_DIR = 'objbc'
+  OBJ_SUFFIX = 'obj'
+  MAKE='bmake.bat -DUSEBC'
+elsif TOOLCHAIN == 'mingw64' then
+  if not File.exist? 'C:\mingw64\bin' then
+  	raise new Exception("MINGW64 not found in C:\\mingw64!")
+  end
+  ENV['MINGW_DIR'] ='C:\MINGW64'
+  ENV['MINGW'] = '__MINGW64__'
+  ENV['USEMINGW_ARG'] = '-DUSEMINGW64'
+  OBJ_DIR = 'objmingw'
+  OBJ_SUFFIX = 'obj'
+  MAKE='mingwmake.bat'  
+  ENV["PATH"] = "#{ENV['PATH']};#{ENV['MINGW_DIR']}\\bin"
+elsif (TOOLCHAIN == 'mingw' or TOOLCHAIN == 'mingw32') then
+  if not File.exist? 'C:\mingw\bin' then
+  	raise new Exception("MINGW not found in C:\\mingw!")
+  end
+  ENV['MINGW_DIR'] ='C:\MINGW'
+  ENV['MINGW'] = '__MINGW32__'
+  ENV['USEMINGW_ARG'] = '-DUSEMINGW32'	
+  OBJ_DIR = 'objmingw'
+  OBJ_SUFFIX = 'obj'
+  MAKE='mingwmake.bat'
+  ENV["PATH"] = "#{ENV['PATH']};#{ENV['MINGW_DIR']}\\bin"
+else
+  raise new Exception("Unsupported toolchain: #{TOOLCHAIN}")
+end
+  
+
+
+
+task :'setup' => [ :'setup:pre',
+                   :'setup:main',
+                   :'setup:post' ]
+
+task :'setup:pre'
+task :'setup:post'
+
+task :'setup:main' => [ :'setup:projects', :'setup:project' , :'setup:tasks' ];
+
+task :'setup:projects' do
+  Rake::Stx::Configuration.read_specs(PROJECT_DIRS)
+end
+
+task :'setup:project' =>  :'setup:projects'  do
+  error("PROJECT variable not defined!") if not defined? PROJECT
+  project! PROJECT.to_sym
+
+
+
+  project.apply_imports()
+
+  app_name    = project.app_name    || 'smalltalkx'
+  app_version = project.app_version || '6.2.5'
+
+  defined? BUILD_NAME or BUILD_NAME = "#{app_name}-#{app_version}_#{ARCH}-#{PLATFORM}"
+
+end
+
+task :'setup:tasks' => :'setup:tasks:internal'
+
+task :'setup:tasks:internal' => :'setup:project' do
+
+  project().tasks.each do | t |
+    t.define!
+  end
+
+
+  # compute required packages - bit hacky!
+  pkgs_all  = project.packages.collect { | p | p.name }
+  if project.application
+    pkgs_all += [ project.application.name ]
+    pkgs_reqd = Rake::Task[project.application.name].all_prerequisites_sorted
+  else
+    pkgs_reqd = (project.packages.select { | p | not p.link  }).collect { | p | p.name }
+  end
+
+  pkgs_reqd = pkgs_reqd.reject { | p | not pkgs_all.include? p }
+  pkgs_reqd = pkgs_reqd.collect { | p | project.package(p) }
+  if project.application
+     pkgs_reqd_and_app = pkgs_reqd + [ project.application ]
+  else
+    pkgs_reqd_and_app = pkgs_reqd
+  end
+
+  info "Required packages (in topological order):"
+  pkgs_reqd.each do | pkg |
+    info "  #{pkg.name}"
+  end
+
+
+  # compile task
+  if project.application
+    task :'compile:application' => project.application.name
+  else
+    task :'compile:application'
+  end
+
+  info "Defining task for packages..."
+
+  pkgs_reqd_and_app.each do | pkg |
+
+    info "Defining task for package #{pkg.name}"
+
+    if unix? #and not File.exist? BUILD_DIR / pkg.directory / 'makefile'
+      task pkg.name => [ BUILD_DIR / pkg.directory / 'makefile' ]
+      file BUILD_DIR / pkg.directory / 'makefile' do
+        chdir BUILD_DIR / pkg.directory do
+          if not system "sh #{ pkg.top() / 'stx' / 'rules' / 'stmkmf'}"
+            raise Exception.new("Canmot run stmkmf for #{pkg.directory}")
+          end
+        end
+      end
+    end
+
+    #require 'find'
+    #[ 'bitmaps', 'resources' ].each do | dir |
+    #  path = BUILD_DIR / pkg.directory() / dir
+    #  if File.exist?(path)
+    #    Find.find(File.expand_path(path)) do | file |
+    #      if FileTest.directory?(file)
+    #        if (File.basename(file) == '..') || (File.basename(file) == '.')
+    #          Find.prune       # Don't look any further into this directory.
+    #        else
+    #          if File.exists?(File.join(file, '.svn'))
+    #            rm_rf File.join(file, '.svn')
+    #            #Find.prune
+    #          end
+    #        end
+    #      end
+    #    end
+    #  end
+    #end
+
+    task "#{pkg.name}" => [ "#{pkg.name}:pre", "#{pkg.name}:main", "#{pkg.name}:post" ]
+
+    task "#{pkg.name}:pre"
+    task "#{pkg.name}:post"
+
+    task "#{pkg.name}:main" do | t |
+      make_vars = ""
+      d = win32? ? '-D' : ''
+      q = win32? ? '"'  : "'"
+
+
+      if unix?
+        make_vars += "STC=#{STC}"
+      end
+      if pkg.application? and not win32?
+        liblist=''
+        libobjs=''
+        link_libobjs=''
+
+        pkgs_reqd.each do | p |
+          if not p.application?
+              if p.link
+                liblist += "#{p.dll_name_without_suffix()} "
+                libobjs += "#{File.join(pkg.top() , p.directory(), p.dll_name())} "
+                link_libobjs += "#{p.dll_name()} "
+              end
+          end
+        end
+
+
+        make_vars += " #{q}#{d}LIBLIST=#{liblist}#{q}"
+        make_vars += " #{q}#{d}LIBOBJS=#{libobjs}#{q}"
+        make_vars += " #{q}#{d}LINK_LIBOBJS=#{link_libobjs}#{q}"
+      end
+
+      # Update stc flags,
+      stc_flags = pkg.stc_flags
+
+      if stc_flags
+        make_vars += " #{q}#{d}STC_CMD_OPT=#{stc_flags}#{q}"
+      end
+
+      if File.exist? BUILD_DIR / pkg.directory / 'GNUmakefile'
+        rm BUILD_DIR / pkg.directory / 'GNUmakefile'
+      end
+
+      info "Compiling #{pkg.name}..."
+      make_vars = "#{make_vars} #{DEBUG}"
+      chdir BUILD_DIR / pkg.directory do
+        if pkg.application? and win32?
+          make 'exe'
+          make 'RESOURCEFILES'
+        else
+          # Somewhat stupid detection whether we run recent St/X or not...
+          if File.exist? BUILD_DIR / 'stx' / 'libbasic2' / 'Makefile.init'
+            make "#{make_vars} full"
+          else
+            make "#{make_vars}"
+          end
+        end
+      end
+
+      if pkg.application?  and unix?
+        chdir BUILD_DIR / 'stx' / 'librun' do
+          make
+        end
+      end
+
+
+
+    end
+
+    if pkg.application?
+      if win32?
+        task pkg.name => BUILD_DIR / pkg.directory / 'modules.stx'
+
+        task BUILD_DIR / pkg.directory / 'modules.stx' do | t |
+          rm t.name if File.exist? t.name
+          File.open(t.name, 'w') do | f |
+            pkgs_reqd.each do | p |
+              if not p.application? and File.exist? BUILD_DIR / p.directory / OBJ_DIR / p.dll_name()
+                f.puts p.dll_name_without_suffix()
+              end
+            end
+          end
+        end
+
+        pkgs_reqd.each do | p |
+          if not p.application?
+            task pkg.name => BUILD_DIR / pkg.directory / p.dll_name()
+
+            file BUILD_DIR / pkg.directory / p.dll_name() => BUILD_DIR / p.directory / OBJ_DIR / p.dll_name() do
+              cp BUILD_DIR / p.directory / OBJ_DIR / p.dll_name(),
+              BUILD_DIR / pkg.directory / p.dll_name()
+            end
+          end
+
+          if win32_wine?
+            file BUILD_DIR / pkg.directory / p.dll_name() do
+              cp BUILD_DIR / p.directory / OBJ_DIR / p.dll_name(),
+              BUILD_DIR / pkg.directory / p.dll_name()
+            end
+          end
+
+        end
+      else # UNIX
+        task "#{pkg.name}:main" => BUILD_DIR / pkg.directory / 'modulList.stc'
+
+        task BUILD_DIR / pkg.directory / 'modulList.stc' do | t |
+          rm t.name if File.exist? t.name
+        end
+
+        task "#{pkg.name}:main" => BUILD_DIR / pkg.directory / 'modulList.c'
+
+        task BUILD_DIR / pkg.directory / 'modulList.c' do | t |
+          rm t.name if File.exist? t.name
+        end
+      end
+    end
+  end
+
+end
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/smalltalk-utils.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,51 @@
+module Rake::StX
+
+  # Simple utility to add records to smalltalk ChangeSet
+  class ChangeSet
+    def initialize(filename) 
+      @filename = filename
+    end
+
+    # Evaluates a block for each standard changeset found in
+    # given directory (BUILD_DIR usually)
+    def self.standardChangesetsDo(root)      
+      if File.exist?(f = root / 'stx' / 'st.chg') 
+        yield(ChangeSet.new(f)) if block_given?
+      end
+      if File.exist?(f = root / 'project' / 'smalltalk' / 'st.chg')
+        yield(ChangeSet.new(f)) if block_given?
+      end
+    end
+
+    def addInfoChange(info)       
+      if unix?
+        hostname = `hostname`.chop
+        username = ENV['USER']
+      else
+        hostname = '???'
+        username = ENV['USERNAME']
+      end
+      timestamp = Time.now.strftime("%d-%m-%Y %H:%M:%S")
+      file = File.open(@filename, "a")
+      begin
+        file.print("'---- #{info} #{username}@#{hostname} #{timestamp} ----'!\n")
+      ensure
+        file.close
+      end
+    end
+
+    def addTimestampInfo()
+      addInfoChange('timestamp')
+    end
+
+    def addRakeUpdateInfo()
+      addInfoChange('rake update')
+    end
+
+    def addRakeCompileInfo()
+      addInfoChange('rake compile')
+    end
+
+
+  end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/support.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,18 @@
+module Rake
+end
+
+module Rake::StX
+end
+
+ARGV.each do | arg |
+  if arg =~ /[A-Za-z_]\w*=[^=]*/
+    name_and_value = arg.split('=')
+    self.class.const_set(name_and_value[0], name_and_value[1])  
+  end
+end
+
+require 'rakelib/extensions.rb'
+require 'rakelib/rbspec.rb'
+require 'rakelib/vcs.rb'
+require 'rakelib/smalltalk-utils.rb'
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/test.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,138 @@
+
+desc "Run tests"
+task :'test' => :'test:all'
+
+desc "Run tests (alias for target test)"
+task :'tests' => :'test'
+
+
+task :'setup:tasks' => :'setup:tasks:test'
+
+def run_report(app, packages, report, global_opts = '', report_opts = '')
+  #run_report_st = BUILD_DIR / 'stx' / 'goodies' / 'builder' / 'reports' / 'report-runner-old.st'
+  run_report_st = BUILD_DIR / 'stx' / 'goodies' / 'builder' / 'reports' / 'report-runner.st'
+  coveragerportformat_dot_st = BUILD_DIR / 'stx' / 'goodies' / 'builder' / 'reports' / 'Builder__CoverageReportFormat.st'
+
+  report_dir = File.expand_path(REPORT_DIR)
+
+
+  if app
+    exe_dir = BUILD_DIR / app.directory
+    if win32?
+      exe = "#{app.executable}.com"
+    else
+      exe = "./#{app.executable}"
+    end
+  else
+    exe_dir = BUILD_DIR / 'stx' / 'projects' / 'smalltalk'
+    if win32?
+      exe = "stx.com"
+    else
+      exe = "./stx"
+    end
+  end
+
+  chdir exe_dir do
+
+    packages_args = ''
+    packages.each { | p | packages_args += " -p #{p}" }
+
+    if File.exist?(coveragerportformat_dot_st)
+        runner_opts = "-abortOnSEGV -I --execute #{run_report_st}"
+    else
+        runner_opts = "-I -f #{run_report_st}"
+    end
+
+
+    #sh "#{exe} -I --quick -execue f #{run_report_st} -o #{report_dir} -r #{report} -p #{pkg.name}"
+    sh "#{exe} #{runner_opts} #{global_opts} -D #{report_dir} -r #{report} #{report_opts} #{packages_args}"
+  end
+end
+
+task :'setup:tasks:test' do
+  app = project.application
+  packages = []
+  project.packages.each do | pkg |
+    if pkg.test
+      task "test:package:#{pkg.name}" => [ 'stx:goodies/builder/reports', REPORT_DIR ] do
+        if pkg.coverage
+          run_report(app, [ pkg.name ], 'Builder::TestReport',  '', '--coverage')
+        else
+          run_report(app, [ pkg.name ], 'Builder::TestReport')
+	end
+      end
+      task :'test:packages' => "test:package:#{pkg.name}"
+    end
+
+    if pkg.lint
+      task "lint:package:#{pkg.name}" => [ 'stx:goodies/builder/reports', REPORT_DIR ]  do
+	#puts "LINT DISABLED (because of some bug in recent SmallLint - runs out of memory)"
+	run_report(app, [ pkg.name ], 'Builder::LintReport')
+      end
+      task :'lint:packages' => "lint:package:#{pkg.name}"
+    end
+  end
+end
+
+task :'setup:tasks' => :'setup:tasks:test'
+task :'test:setup' => :'setup'
+task :'lint:setup' => :'setup'
+
+namespace :'test' do
+  task :'all' => [ :'setup', :'pre', :'main', :'post' ]
+  task :'pre'
+  task :'post'
+
+  directory REPORT_DIR
+
+  task :'setup'
+
+  task :'main' => [:'setup', :'packages' ]
+
+  task :'packages'
+end
+
+desc "Run static analysis on the code (SmallLint)"
+task :'lint' => :'lint:all'
+
+
+namespace :'lint' do
+  task :'all' => [ :'setup', :'pre', :'main', :'post' ]
+  task :'pre'
+  task :'post'
+
+  directory REPORT_DIR
+
+  task :'setup'
+
+  task :'main' => [:'setup', :'packages' ]
+
+  task :'packages'
+end
+
+
+
+task BUILD_DIR / 'stx' / 'goodies' / 'builder' / 'reports'  => BUILD_DIR do
+  if File.exist?(BUILD_DIR / 'stx' / 'goodies' / 'builder' / 'reports')
+    update(:'swing:hg', 'stx/goodies/builder', :branch => 'jv')
+  else
+    checkout(:'swing:hg', 'stx/goodies/builder', :branch => 'jv')
+  end
+end
+
+#task :'compile:post' => [ :'stx:builder/hudson', :'test' ]
+
+task 'stx:goodies/builder/reports' => [ BUILD_DIR / 'stx' / 'goodies' / 'builder' / 'reports',
+					:'compile:config' ] do
+  chdir BUILD_DIR / 'stx' / 'goodies' / 'sunit' do
+    make
+  end
+  chdir BUILD_DIR / 'stx' / 'goodies' / 'builder' / 'reports' do
+    if (unix? and File.exist?("Makefile.init"))
+      make "-f" "Makefile.init"
+    else
+      make
+    end
+  end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rakelib/vcs.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,321 @@
+module Rake
+end
+
+module Rake::StX
+end
+
+module Rake::Stx::VCS
+
+  class CheckoutException < Exception
+  end # class CheckoutException
+
+
+  def self._check_type(type)
+    if (type != :cvs and type != :svn and type != :git and type != :hg and type != :hgsvn and type != :hgcvs)
+      raise CheckoutException.new("Unknown version control system type (#{type})")
+    end
+  end
+
+  def self.update(type, repository, directory, *params)
+    self._check_type(type)
+    if params.size() > 0
+      p = params.last
+    else
+      p = {}
+    end
+    root = p[:root] || BUILD_DIR
+    wc = root / directory
+    if (! File.exist? wc)
+      self.checkout(type, repository, directory, *params)
+      return
+    end
+    case type
+      when :svn    then _update_svn(wc)
+      when :cvs    then _update_cvs(wc)
+      when :git    then _update_git(wc, repository, directory, *params)
+      when :hg     then _update_hg(wc, repository, directory, *params)
+      when :hgsvn  then _update_hg_svn(wc)
+      when :hgcvs  then _update_hg_cvs(wc)
+    end
+  end
+
+  def self._update_hg_svn(wc)
+    _update_hg(wc)
+  end
+
+  def self._update_hg_cvs(wc)
+    if (File.exist? wc / '.hg')
+        _update_hg(wc)
+    else
+        _update_cvs(wc)
+    end
+  end
+
+  def self._update_git_svn(wc)
+    cmd = %W{git svn rebase}
+    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    puts "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    FileUtils::chdir(wc) do
+      Rake::FileUtilsExt::when_writing(cmd) do
+        if (not system(*cmd))
+          raise CheckoutException.new("GIT-SVN: Cannot update #{wc}")
+        end
+      end
+    end
+  end
+
+  def self._update_hg(wc, repository = nil, directory = nil, *params)
+    url = ''
+    if repository != nil and directory != nil then
+      if params.size() > 0
+        p = params.last
+      else
+        p = {}
+      end
+      separator = p[:separator] || '.'
+      url = "#{repository}/#{directory.gsub('/', separator)}"
+    end
+    cmd = %W{hg pull #{url}}
+
+    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    puts "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    Rake::FileUtilsExt::chdir(wc) do
+      Rake::FileUtilsExt::when_writing(cmd) do
+        if (not system(*cmd))
+          raise CheckoutException.new("HG: Cannot pull #{wc}")
+        end
+      end
+    end
+
+    # Get bookmark if any...
+    bookmark = nil
+    Rake::FileUtilsExt::chdir(wc) do
+      Rake::FileUtilsExt::when_writing(cmd) do
+    	bookmarks = `hg log --template "{bookmarks}" -r "p1()"`
+    	puts "bookmarks: >>#{bookmarks}<<"
+    	bookmark = bookmarks.split(' ')[0]
+      end
+    end
+
+    cmd = %W{hg update}
+    puts "bookmark: #{bookmark}"
+    if bookmark && bookmark != '' then
+
+    	cmd << '-r' << "#{bookmark}"
+    end
+    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    puts "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    Rake::FileUtilsExt::chdir(wc) do
+      Rake::FileUtilsExt::when_writing(cmd) do
+        if (not system(*cmd))
+          raise CheckoutException.new("HG: Cannot update #{wc}")
+        end
+      end
+    end
+
+  end
+
+
+  def self._update_svn(wc)
+    d = wc
+    while ((File.basename d) != '/')
+        if File.exist?(d / '.hg' / 'svn')
+            _update_hg(d)
+            return
+        end
+        if File.exist?(d / '.git' / 'svn')
+            _update_git_svn(d)
+            return
+        end
+        d = File.expand_path('..', d)
+    end
+    cmd = %W{svn update}
+    # If we're running on Jenkins, force their version:
+    # if ENV['HUDSON_URL'] or ENV['JENKINS_URL']
+    #   cmd << ' --accept' << 'theirs-full'
+    # end
+    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    Rake::FileUtilsExt::chdir(wc) do
+      Rake::FileUtilsExt::when_writing(cmd) do
+        if (not system(*cmd))
+          raise CheckoutException.new("SVN: Cannot update #{wc}")
+        end
+      end
+    end
+	cmd = %W{svn upgrade}
+	system(*cmd)
+
+    cmd = %W{svn --non-interactive --trust-server-cert update}
+    # If we're running on Jenkins, force their version:
+    # if ENV['HUDSON_URL'] or ENV['JENKINS_URL']
+    #   cmd << ' --accept' << 'theirs-full'
+    # end
+    info "executing cmd: '#{cmd.join(" ")}' in '#{wc}'"
+    Rake::FileUtilsExt::chdir(wc) do
+      Rake::FileUtilsExt::when_writing(cmd) do
+        if (not system(*cmd))
+          raise CheckoutException.new("SVN: Cannot update #{wc}")
+        end
+      end
+    end
+  end
+
+  def self._update_cvs(wc)
+    if not File.exist?(wc / 'CVS')
+      return
+    end
+    cmd = %W{cvs -z 9 update -A -d}
+    info "executing cmd: '#{cmd.join(' ')}}' in '#{wc}'"
+    if File.directory?(wc)
+      Rake::FileUtilsExt::chdir(wc) do
+        Rake::FileUtilsExt::when_writing(cmd) do
+          if (not system(*cmd))
+            raise CheckoutException.new("CVS: Cannot update #{wc}")
+          end
+        end
+      end
+    end
+  end
+
+  def self.checkout(type, repository, directory, *params)
+    self._check_type(type)
+    if params.size() > 0
+      p = params.last
+    else
+      p = {}
+    end
+    root = p[:root] || BUILD_DIR
+    branch = p[:branch]
+    if branch == nil
+      if type == :svn
+        branch = 'trunk'
+      elsif type == :hg
+        branch = 'default'
+      end
+    end
+
+    wc = root / directory
+    if (File.exist? wc)
+      self.update(type, repository, directory, *params)
+      return
+    end
+
+    if (not File.exists? File.dirname(wc))
+      begin
+        FileUtils.mkdir_p(File.dirname(wc))
+      rescue => ex
+        raise CheckoutException.new("Cannot create directory for working copy (#{ex})")
+      end
+    end
+    case type
+      when :svn    then _checkout_svn(repository, directory, branch, root, *params)
+      when :cvs    then _checkout_cvs(repository, directory, branch, root, *params)
+      when :git    then _checkout_git(repository, directory, branch, root, *params)
+      when :hg     then _checkout_hg(repository, directory, branch, root, *params)
+      when :hgsvn  then _checkout_hg_svn(repository, directory, branch, root, *params)
+      when :hgcvs  then _checkout_hg_cvs(repository, directory, branch, root, *params)
+    end
+
+  end
+
+  def self._checkout_svn(repository, directory, branch, root, *params)
+    url = "#{repository}/#{directory}/#{branch}"
+    cmd = %W{svn --non-interactive --trust-server-cert co #{url} #{root / directory}}
+    info "executing cmd: '#{cmd}'"
+    Rake::FileUtilsExt::when_writing(cmd) do
+      if (not system(*cmd))
+        raise CheckoutException.new("SVN: Cannot checkout from #{url}")
+      end
+    end
+  end
+
+  def self._checkout_hg_impl(repository, package, directory, branch, root, *params)
+    url = "#{repository}/#{package}"
+    cmd = %W{hg clone #{url} #{root / directory}}
+    info "executing cmd: '#{cmd}'"
+    Rake::FileUtilsExt::when_writing(cmd) do
+      if (not system(*cmd))
+        raise CheckoutException.new("HG: Cannot clone from #{url}")
+      end
+    end
+    cmd = %W{hg update #{branch}}
+    info "executing cmd: '#{cmd}'"
+    Rake::FileUtilsExt::when_writing(cmd) do
+      Rake::FileUtilsExt::chdir(root / directory) do
+        if (not system(*cmd))
+          raise CheckoutException.new("HG: Cannot switch to branch #{branch}")
+        end
+      end
+    end
+  end
+
+  def self._checkout_hg_svn(repository, directory, branch, root, *params)
+    b = branch
+    if b && b.start_with?('branches/')
+        b = b.slice('branches/'.size..-1)
+    end
+    _checkout_hg_impl(repository, directory, directory, b, root, *params)
+  end
+
+  def self._checkout_hg_cvs(repository, directory, branch, root, *params)
+    raise Exception.new("Cannot checkout HG-CVS repository - you must create WC manually")
+  end
+
+  def self._checkout_hg(repository, directory, branch, root, *params)
+    if params.size() > 0
+      p = params.last
+    else
+      p = {}
+    end
+    separator = p[:separator] || '.'
+
+    _checkout_hg_impl(repository, directory.gsub('/', separator), directory, branch, root)
+  end
+
+  def self._checkout_cvs(repository, directory, branch, root, *params)
+    cmd = %W{cvs -z 9 -d #{repository} co #{directory}}
+    info "executing cmd: '#{cmd}' in '#{root}'"
+    Rake::FileUtilsExt::when_writing(cmd) do
+      Rake::FileUtilsExt::chdir root do
+        if (not system(*cmd))
+          raise CheckoutException.new("CVS: Cannot checkout #{directory}from #{repository}")
+        end
+      end
+    end
+  end
+end # module Rake::Stx::VCS
+
+def checkout(repo_name, directory, *params)
+  # repository should be symbolic name
+  if (repo = project().repository?(repo_name))
+    Rake::Stx::VCS.checkout(repo.type, repo.url, directory, *params)
+  else
+    error("checkout(): No repository found (#{repo_name})")
+  end
+end
+
+def update(repo_name, directory, *params)
+  # repository should be symbolic name
+  if (repo = project().repository?(repo_name))
+    Rake::Stx::VCS.update(repo.type, repo.url, directory, *params)
+  else
+    error("update(): No repository found (#{repo_name})")
+  end
+end
+
+def cvs(repository, directory, *params)
+  Rake::Stx::VCS.checkout(:cvs, repository, directory, *params)
+end
+
+def svn(repository, directory, *params)
+  Rake::Stx::VCS.checkout(:svn, repository, directory, *params)
+end
+
+def hg(repository, directory, *params)
+  Rake::Stx::VCS.checkout(:hg, repository, directory, *params)
+end
+
+def git(repository, directory, *params)
+  Rake::Stx::VCS.checkout(:git, repository, directory, *params)
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/baseline.deps.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,186 @@
+# Package dependencies.
+# Automatically generated by project defintion.
+
+task "stx:libbasic"
+
+task "stx:libcompat" => "stx:libview"
+task "stx:libcompat" => "stx:libwidg"
+task "stx:libcompat" => "stx:libview2"
+task "stx:libcompat" => "stx:libbasic2"
+task "stx:libcompat" => "stx:libwidg2"
+task "stx:libcompat" => "stx:libbasic"
+task "stx:libcompat" => "stx:libbasic3"
+task "stx:libcompat" => "stx:libcomp"
+task "stx:libcompat" => "stx:libtool"
+
+task "stx:libwidg3" => "stx:libview"
+task "stx:libwidg3" => "stx:libui"
+task "stx:libwidg3" => "stx:libview2"
+task "stx:libwidg3" => "stx:libwidg"
+task "stx:libwidg3" => "stx:libbasic2"
+task "stx:libwidg3" => "stx:libwidg2"
+task "stx:libwidg3" => "stx:libbasic"
+
+task "stx:goodies/refactoryBrowser/helpers" => "stx:libbasic"
+
+
+task "stx:goodies/refactoryBrowser/parser" => "stx:libbasic"
+
+task "stx:goodies/refactoryBrowser/refactoring" => "stx:goodies/refactoryBrowser/parser"
+task "stx:goodies/refactoryBrowser/refactoring" => "stx:libview"
+task "stx:goodies/refactoryBrowser/refactoring" => "stx:goodies/refactoryBrowser/changes"
+task "stx:goodies/refactoryBrowser/refactoring" => "stx:libbasic"
+task "stx:goodies/refactoryBrowser/refactoring" => "stx:libcomp"
+task "stx:goodies/refactoryBrowser/refactoring" => "stx:libtool"
+task "stx:goodies/refactoryBrowser/refactoring" => "stx:goodies/refactoryBrowser/helpers"
+
+task "stx:libwidg" => "stx:libview2"
+task "stx:libwidg" => "stx:libview"
+task "stx:libwidg" => "stx:libbasic2"
+task "stx:libwidg" => "stx:libbasic"
+
+task "stx:goodies/sunit" => "stx:libview2"
+task "stx:goodies/sunit" => "stx:libview"
+task "stx:goodies/sunit" => "stx:libbasic"
+
+task "stx:libview2" => "stx:libview"
+task "stx:libview2" => "stx:libbasic2"
+task "stx:libview2" => "stx:libbasic"
+
+task "stx:libbasic2" => "stx:libbasic"
+
+task "stx:libview" => "stx:libbasic2"
+task "stx:libview" => "stx:libbasic"
+
+task "stx:libhtml" => "stx:libwidg"
+task "stx:libhtml" => "stx:libview"
+task "stx:libhtml" => "stx:libbasic"
+
+task "stx:goodies/refactoryBrowser/lint" => "stx:goodies/refactoryBrowser/changes"
+task "stx:goodies/refactoryBrowser/lint" => "stx:goodies/refactoryBrowser/browser"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libbasic3"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libcompat"
+task "stx:goodies/refactoryBrowser/lint" => "stx:goodies/refactoryBrowser/parser"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libbasic2"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libview2"
+task "stx:goodies/refactoryBrowser/lint" => "stx:goodies/sunit"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libwidg"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libbasic"
+task "stx:goodies/refactoryBrowser/lint" => "stx:goodies/refactoryBrowser/helpers"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libview"
+task "stx:goodies/refactoryBrowser/lint" => "stx:libtool"
+
+task "stx:libtool2" => "stx:libview"
+task "stx:libtool2" => "stx:libui"
+task "stx:libtool2" => "stx:libview2"
+task "stx:libtool2" => "stx:libwidg"
+task "stx:libtool2" => "stx:libbasic2"
+task "stx:libtool2" => "stx:libwidg2"
+task "stx:libtool2" => "stx:libbasic"
+task "stx:libtool2" => "stx:libbasic3"
+task "stx:libtool2" => "stx:libcomp"
+task "stx:libtool2" => "stx:libtool"
+task "stx:libtool2" => "stx:libview3"
+
+task "stx:libcomp" => "stx:libbasic"
+
+task "stx:goodies/refactoryBrowser/changes" => "stx:goodies/refactoryBrowser/helpers"
+task "stx:goodies/refactoryBrowser/changes" => "stx:goodies/refactoryBrowser/parser"
+task "stx:goodies/refactoryBrowser/changes" => "stx:libbasic3"
+task "stx:goodies/refactoryBrowser/changes" => "stx:libbasic"
+
+task "stx:goodies/refactoryBrowser/browser" => "stx:goodies/refactoryBrowser/parser"
+task "stx:goodies/refactoryBrowser/browser" => "stx:libview"
+task "stx:goodies/refactoryBrowser/browser" => "stx:libview2"
+task "stx:goodies/refactoryBrowser/browser" => "stx:libwidg"
+task "stx:goodies/refactoryBrowser/browser" => "stx:libcompat"
+task "stx:goodies/refactoryBrowser/browser" => "stx:libbasic"
+task "stx:goodies/refactoryBrowser/browser" => "stx:goodies/refactoryBrowser/helpers"
+
+task "stx:libboss" => "stx:libbasic"
+
+task "stx:libtool" => "stx:goodies/refactoryBrowser/parser"
+task "stx:libtool" => "stx:goodies/refactoryBrowser/changes"
+task "stx:libtool" => "stx:libui"
+task "stx:libtool" => "stx:libview"
+task "stx:libtool" => "stx:libview2"
+task "stx:libtool" => "stx:libwidg"
+task "stx:libtool" => "stx:libbasic2"
+task "stx:libtool" => "stx:libwidg2"
+task "stx:libtool" => "stx:libbasic"
+task "stx:libtool" => "stx:libbasic3"
+task "stx:libtool" => "stx:libboss"
+task "stx:libtool" => "stx:libcomp"
+
+task "stx:libwidg2" => "stx:libview"
+task "stx:libwidg2" => "stx:libview2"
+task "stx:libwidg2" => "stx:libwidg"
+task "stx:libwidg2" => "stx:libbasic2"
+task "stx:libwidg2" => "stx:libbasic"
+
+task "stx:libbasic3" => "stx:libbasic2"
+task "stx:libbasic3" => "stx:libbasic"
+#task "stx:libbasic3" => "stx:libdb/libodbc"    #sigh
+task "stx:libbasic3" => "stx:libdb/libsqlite"  #sigh
+
+task "stx:libview3" => "stx:libview2"
+task "stx:libview3" => "stx:libview"
+task "stx:libview3" => "stx:libbasic2"
+task "stx:libview3" => "stx:libui"
+task "stx:libview3" => "stx:libbasic"
+
+task "stx:libui" => "stx:libview2"
+task "stx:libui" => "stx:libview"
+task "stx:libui" => "stx:libbasic"
+task "stx:libui" => "stx:libwidg2"
+
+task "stx:projects/smalltalk" => "stx:libtool2"
+task "stx:projects/smalltalk" => "stx:libwidg2"
+task "stx:projects/smalltalk" => "stx:goodies/refactoryBrowser/changes"
+task "stx:projects/smalltalk" => "stx:libbasic3"
+task "stx:projects/smalltalk" => "stx:goodies/refactoryBrowser/lint"
+task "stx:projects/smalltalk" => "stx:goodies/refactoryBrowser/refactoring"
+task "stx:projects/smalltalk" => "stx:libcomp"
+task "stx:projects/smalltalk" => "stx:libcompat"
+task "stx:projects/smalltalk" => "stx:goodies/refactoryBrowser/parser"
+task "stx:projects/smalltalk" => "stx:libbasic2"
+task "stx:projects/smalltalk" => "stx:libui"
+task "stx:projects/smalltalk" => "stx:libview2"
+task "stx:projects/smalltalk" => "stx:libhtml"
+task "stx:projects/smalltalk" => "stx:libwidg"
+task "stx:projects/smalltalk" => "stx:libboss"
+task "stx:projects/smalltalk" => "stx:libbasic"
+task "stx:projects/smalltalk" => "stx:goodies/refactoryBrowser/helpers"
+task "stx:projects/smalltalk" => "stx:libview"
+task "stx:projects/smalltalk" => "stx:libwidg3"
+task "stx:projects/smalltalk" => "stx:libtool"
+task "stx:projects/smalltalk" => "stx:libjavascript"
+task "stx:projects/smalltalk" => "stx:goodies/libdbase" if not win32?
+
+task "stx:goodies/libdbase" => "stx:libbasic"
+task "stx:goodies/libdbase" => "stx:libbasic2"
+
+# Manually added
+
+task "stx:goodies/xml/stx" => "stx:libbasic"
+task "stx:goodies/xml/stx" => "stx:libbasic2"
+task "stx:goodies/xml/stx" => 'stx:goodies/xml/vw'
+
+task "stx:goodies/xmlsuite/xmlreaderimpl" => 'stx:goodies/xml/vw'
+task "stx:goodies/xmlsuite/xmlreaderimpl" => 'stx:goodies/xmlsuite/core'
+task "stx:goodies/xmlsuite/xmlreaderimpl" => 'stx:libbasic'
+
+task "stx:libjavascript" => "stx:libbasic3"
+task "stx:libjavascript" => "stx:libcomp"
+task "stx:libjavascript" => "stx:libbasic"
+
+task "stx:libdb" => "stx:libbasic"
+task "stx:libdb" => "stx:libcomp"
+
+task "stx:libdb/libodbc" => "stx:libbasic"
+task "stx:libdb/libodbc" => "stx:libbasic2"
+task "stx:libdb/libodbc" => "stx:libcomp"
+task "stx:libdb/libodbc" => "stx:libdb"
+
+task "stx:libdb/libsqlite" => "stx:libbasic"
+task "stx:libdb/libsqlite" => "stx:libbasic2"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/baseline.rbspec	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,197 @@
+load 'baseline.deps.rake'
+
+project :'stx:repositories' do
+
+  # Hack for core developers..."
+  case USER
+  when 'jv' # Jan Vrany
+      user = 'vranyj1'
+  when 'm' # Marcel Hlopko
+      user = 'hlopkmar'
+  when 'roztocidlo' # Jan Kurs HTPC
+      user = 'kursjan'
+  else
+    user = USER
+  end
+
+  # Hack for JV :-)
+
+  if USER == 'jv'
+    swing_baseline_url = ":ext:vrany@dialin.exept.de/cvs/stx"
+  else
+    swing_baseline_url = ":ext:#{user}@swing.fit.cvut.cz/var/local/cvs"
+  end
+
+  repository :'swing:baseline' do
+    type :cvs
+    url swing_baseline_url
+  end
+
+  repository :'swing' do
+    type :svn
+    url "https://#{user}@swing.fit.cvut.cz/svn"
+  end
+
+  repository :'swing:hgsvn' do
+    type :hgsvn
+    url "https://#{user}@swing.fit.cvut.cz/svn"
+  end
+
+  repository :'swing:hg' do
+    type :hg
+    # url "https://#{user}@swing.fit.cvut.cz/hg"
+    url "ssh://#{user}@swing.fit.cvut.cz//var/local/hg"
+  end
+
+  repository :'swing:private' do
+    type :svn
+    url "svn+ssh://#{user}@192.168.12.2/svn"
+  end
+
+  repository :'swing:private:hg' do
+    type :hg
+    url "ssh://#{user}@192.168.12.2//hg"
+  end
+
+  repository :'swing:private:cvs' do
+    type :cvs
+    url ":ext:#{user}@192.168.12.2/cvs"
+  end
+
+  repository :'bitbucket:janvrany' do
+    type :hg
+    url "https://bitbucket.org/janvrany"
+    separator '-'
+  end
+end
+
+project :'stx:baseline' do
+
+  import :'stx:repositories'
+
+  repository :'swing:baseline'
+  package "stx:libbasic"
+  package "stx:goodies/refactoryBrowser/helpers"
+  package "stx:goodies/refactoryBrowser/parser"
+  package "stx:libbasic2"
+  package "stx:libcomp"
+  package "stx:libcompat"
+  package "stx:libview"
+  package "stx:libbasic3"
+  package "stx:libdb"
+  package "stx:libdb/libodbc"
+  package "stx:libdb/libsqlite"
+  package "stx:libview2"
+  package "stx:libboss"
+  package "stx:goodies/refactoryBrowser/changes"
+  package "stx:libwidg"
+  package "stx:libhtml"
+  package "stx:libwidg2"
+  package "stx:libui"
+  package "stx:libview3"
+  package "stx:libwidg3"
+  package "stx:libtool"
+  package "stx:libjavascript"
+  package "stx:goodies/refactoryBrowser/refactoring"
+  package "stx:goodies/refactoryBrowser/lint"
+  package "stx:goodies/refactoryBrowser/browser"
+  package "stx:libtool2"
+  package "stx:goodies/libdbase" if not win32?
+
+  application 'stx:projects/smalltalk'
+
+  tasks do
+
+    task :'checkout:buildtools' => [ BUILD_DIR / 'stx' / "rules",
+				     BUILD_DIR / 'stx' / "configurations",
+				     BUILD_DIR / 'stx' / "support",
+				     BUILD_DIR / 'stx' / "stc",
+				     BUILD_DIR / 'stx' / "librun",
+				     BUILD_DIR / 'stx' / "RELEASE",
+				     # needed by applications for *.rc stuff
+                                     BUILD_DIR / 'stx' / 'projects' / 'smalltalk',
+                                     # documentation
+                                     BUILD_DIR / 'stx' / 'doc' / 'online' / 'english',
+                                     BUILD_DIR / 'stx' / 'doc' / 'online' / 'pictures',
+                                     BUILD_DIR / 'stx' / 'doc' / 'online' / 'icons',
+                                     # various icons (country flags etc)
+                                     BUILD_DIR / 'stx' / 'goodies' / 'bitmaps'
+				   ]
+
+    file BUILD_DIR / 'stx' / 'rules'  => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/rules'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'RELEASE'  => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/RELEASE'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'configurations' => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/configurations'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'doc' / 'online' / 'english'  => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/doc/online/english'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'doc' / 'online' / 'pictures'  => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/doc/online/pictures'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'doc' / 'online' / 'icons'  => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/doc/online/icons'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'goodies' / 'bitmaps'   => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/goodies/bitmaps'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'support' => BUILD_DIR do | t |
+      checkout :'swing:baseline', 'stx/support'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'stc' => BUILD_DIR do | t |
+      checkout :'swing:private', 'stx/stc'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'librun' => BUILD_DIR do | t |
+      checkout :'swing:private', 'stx/librun'
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+    file BUILD_DIR / 'stx' / 'projects' / 'smalltalk' do | t |
+      app = project.application
+      repo = :'swing:baseline'
+      branch = nil
+      if (app.name == 'stx:projects/smalltalk' ) 
+      	repo = app.repository
+      	branch = app.branch
+      end
+      checkout repo, 'stx/projects/smalltalk', :branch => branch
+      # the clear is here to avoid multiple checkouts
+      t.clear()
+    end
+
+  end
+
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/jv-branch.deps.rake	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,160 @@
+# Package dependencies, will vanish
+
+task "stx:goodies/monticello" => "stx:libview"
+task "stx:goodies/monticello" => "stx:libview2"
+task "stx:goodies/monticello" => "stx:libbasic2"
+task "stx:goodies/monticello" => "stx:libcompat"
+task "stx:goodies/monticello" => "stx:libwidg2"
+task "stx:goodies/monticello" => "stx:libbasic"
+task "stx:goodies/monticello" => "stx:libbasic3"
+task "stx:goodies/monticello" => "stx:libcomp"
+task "stx:goodies/monticello" => "stx:goodies/communication"
+task "stx:goodies/monticello" => "stx:libtool"
+
+task "stx:goodies/communication" => "stx:libview"
+task "stx:goodies/communication" => "stx:libwidg"
+task "stx:goodies/communication" => "stx:libview2"
+task "stx:goodies/communication" => "stx:libbasic2"
+task "stx:goodies/communication" => "stx:libbasic"
+task "stx:goodies/communication" => "stx:libcomp"
+task "stx:goodies/communication" => "stx:libtool"
+task "stx:goodies/communication" => "stx:libhtml"
+
+task "stx:goodies/sunit" => "stx:libview2"
+task "stx:goodies/sunit" => "stx:libview"
+task "stx:goodies/sunit" => "stx:libbasic"
+
+task "stx:libsvn" => "stx:libview"
+task "stx:libsvn" => "stx:libwidg"
+task "stx:libsvn" => "stx:goodies/xml/vw"
+task "stx:libsvn" => "stx:libview2"
+task "stx:libsvn" => "stx:libbasic2"
+task "stx:libsvn" => "stx:libwidg2"
+task "stx:libsvn" => "stx:libbasic"
+task "stx:libsvn" => "stx:libbasic3"
+task "stx:libsvn" => "stx:libtool2"
+task "stx:libsvn" => "stx:libtool"
+task "stx:libsvn" => "stx:libtool2"
+task "stx:libsvn" => "stx:libhtml"
+
+task "stx:goodies/xml/vw" => "stx:libbasic2"
+task "stx:goodies/xml/vw" => "stx:libbasic3"
+task "stx:goodies/xml/vw" => "stx:libbasic"
+
+task "stx:libcompat" => "stx:libview"
+task "stx:libcompat" => "stx:libwidg"
+task "stx:libcompat" => "stx:libview2"
+task "stx:libcompat" => "stx:libbasic2"
+task "stx:libcompat" => "stx:libwidg2"
+task "stx:libcompat" => "stx:libbasic"
+task "stx:libcompat" => "stx:libbasic3"
+task "stx:libcompat" => "stx:libcomp"
+task "stx:libcompat" => "stx:libtool"
+
+task "stx:projects/smalltalk" => "stx:goodies/smallsense"
+task "stx:projects/smalltalk" => "stx:goodies/smallsense/refactoring_custom"
+task "stx:projects/smalltalk" => "stx:libsvn"
+task "stx:projects/smalltalk" => "stx:libprofiler"
+#task "stx:projects/smalltalk" => "stx:goodies/monticello"
+task "stx:projects/smalltalk" => "stx:goodies/sunit"
+
+task "stx:goodies/roeltyper" => "stx:libbasic"
+task "stx:goodies/roeltyper" => "stx:libcomp"
+task "stx:goodies/roeltyper" => "stx:libtool"
+
+task "stx:goodies/smallsense" => "stx:libbasic"
+task "stx:goodies/smallsense" => "stx:libcomp"
+task "stx:goodies/smallsense" => "stx:goodies/roeltyper"
+task "stx:goodies/smallsense" => "stx:libview2"
+task "stx:goodies/smallsense" => "stx:libwidg"
+task "stx:goodies/smallsense" => "stx:goodies/refactoryBrowser/helpers"
+task "stx:goodies/smallsense" => "stx:goodies/refactoryBrowser/lint"
+task "stx:goodies/smallsense" => "stx:goodies/regex"
+
+task "stx:goodies/smallsense/refactoring_custom" => "stx:libbasic"
+
+
+task "stx:libprofiler" => "stx:libbasic"
+task "stx:libprofiler" => "stx:libcomp"
+
+task "stx:goodies/xmlsuite/core" => "stx:libview"
+task "stx:goodies/xmlsuite/core" => "stx:goodies/xml/vw"
+task "stx:goodies/xmlsuite/core" => "stx:libview2"
+task "stx:goodies/xmlsuite/core" => "stx:libbasic2"
+task "stx:goodies/xmlsuite/core" => "stx:libwidg2"
+task "stx:goodies/xmlsuite/core" => "stx:libbasic"
+task "stx:goodies/xmlsuite/core" => "stx:libcomp"
+task "stx:goodies/xmlsuite/core" => "stx:libtool"
+
+task "stx:goodies/xmlsuite/xmlreaderimpl" => "stx:goodies/xmlsuite/core"
+task "stx:goodies/xmlsuite/xmlreaderimpl" => "stx:goodies/xml/vw"
+task "stx:goodies/xmlsuite/xmlreaderimpl" => "stx:libcomp"
+task "stx:goodies/xmlsuite/xmlreaderimpl" => "stx:libbasic"
+
+task "squeak:graphviz" => 'stx:libbasic'
+task "squeak:graphviz" => 'stx:libcompat'
+task "squeak:graphviz" => 'stx:libview'
+
+task "stx:libwebkit" => 'stx:libbasic'
+task "stx:libwebkit" => 'stx:libbasic2'
+task "stx:libwebkit" => 'stx:libview'
+task "stx:libwebkit" => 'stx:libview2'
+task "stx:libwebkit" => 'stx:libwidg'
+
+task "stx:goodies/petitparser" => "stx:goodies/sunit"
+task "stx:goodies/petitparser" => "stx:libbasic2"
+task "stx:goodies/petitparser" => "stx:libbasic"
+
+task "stx:libjava" => "stx:libwidg2"
+task "stx:libjava" => "stx:goodies/petitparser"
+task "stx:libjava" => "stx:libbasic3"
+task "stx:libjava" => "stx:libcomp"
+task "stx:libjava" => "stx:libbasic2"
+task "stx:libjava" => "stx:libview2"
+task "stx:libjava" => "stx:goodies/sunit"
+task "stx:libjava" => "stx:libhtml"
+task "stx:libjava" => "stx:libwidg"
+task "stx:libjava" => "stx:libbasic"
+task "stx:libjava" => "stx:libview"
+task "stx:libjava" => "stx:libtool"
+
+task "stx:libjava/tools" => "stx:libjava"
+task "stx:libjava/tools" => "stx:libtool"
+
+task "stx:libjava/experiments" => "stx:libjava"
+task "stx:libjava/experiments" => "stx:libbasic"
+
+task "stx:projects/smalltalk" => "stx:libwebkit"
+task "stx:projects/smalltalk" => "stx:libjava"
+task "stx:projects/smalltalk" => "stx:libjava/tools"
+task "stx:projects/smalltalk" => "stx:libjava/experiments"
+
+task "patches" => "stx:libbasic"
+task "patches" => "stx:libview"
+#task "patches" => "stx:goodies/refactoryBrowser/refactoring"
+
+task "stx:goodies/cypress" => "stx:libbasic"
+task "stx:goodies/metacello/base" => "stx:libbasic"
+task "stx:goodies/metacello/core" => "stx:goodies/metacello/base"
+task "stx:goodies/metacello/stx" => "stx:goodies/metacello/core"
+
+task "stx:libscm/common" => "stx:libbasic"
+task "stx:libscm/git" => "stx:libbasic"
+task "stx:libscm/git" => "stx:libscm/common"
+task "stx:libscm/mercurial" => "stx:libbasic"
+task "stx:libscm/mercurial" => "stx:libscm/common"
+task "stx:libscm/mercurial/monticello" => "stx:libscm/mercurial"
+task "stx:libscm/mercurial/monticello" => "stx:libcompat"
+
+task "stx:goodies/ring" => "stx:libbasic"
+task "stx:goodies/ring" => "stx:goodies/refactoryBrowser/parser"
+
+task "stx:goodies/libcairo" => "stx:libbasic"
+task "stx:goodies/libcairo" => "stx:libview"
+task "stx:goodies/loggia" => "stx:libbasic"
+task "stx:goodies/loggia" => "stx:libboss"
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/jv.rbspec	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,150 @@
+# This file contains project definition for JV workset.
+# Probably not usefull for anybody but JV :-)
+
+task "stx:goodies/announcements" => "stx:goodies/sunit"
+task "stx:goodies/announcements" => "stx:libbasic2"
+task "stx:goodies/announcements" => "stx:libbasic"
+
+task "cvut:fel/perseus/core" => "stx:libview"
+task "cvut:fel/perseus/core" => "stx:goodies/announcements"
+task "cvut:fel/perseus/core" => "stx:libview2"
+task "cvut:fel/perseus/core" => "stx:goodies/smaCC"
+task "cvut:fel/perseus/core" => "stx:goodies/sunit"
+task "cvut:fel/perseus/core" => "stx:libbasic2"
+task "cvut:fel/perseus/core" => "stx:libwidg2"
+task "cvut:fel/perseus/core" => "stx:libbasic"
+
+task "cvut:fel/perseus/core_ui" => "stx:libtool2"
+task "cvut:fel/perseus/core_ui" => "stx:libwidg2"
+task "cvut:fel/perseus/core_ui" => "cvut:fel/libutilui"
+task "cvut:fel/perseus/core_ui" => "stx:libcomp"
+task "cvut:fel/perseus/core_ui" => "stx:libbasic2"
+task "cvut:fel/perseus/core_ui" => "stx:libui"
+task "cvut:fel/perseus/core_ui" => "stx:libview2"
+task "cvut:fel/perseus/core_ui" => "stx:libwidg"
+task "cvut:fel/perseus/core_ui" => "stx:libbasic"
+task "cvut:fel/perseus/core_ui" => "stx:libview"
+task "cvut:fel/perseus/core_ui" => "cvut:fel/perseus/core"
+task "cvut:fel/perseus/core_ui" => "stx:libtool"
+
+task "cvut:fel/libutilui" => "stx:libview"
+task "cvut:fel/libutilui" => "stx:libui"
+task "cvut:fel/libutilui" => "stx:libview2"
+task "cvut:fel/libutilui" => "stx:libwidg"
+task "cvut:fel/libutilui" => "stx:goodies/sunit"
+task "cvut:fel/libutilui" => "stx:libbasic2"
+task "cvut:fel/libutilui" => "stx:libwidg2"
+task "cvut:fel/libutilui" => "stx:libbasic"
+task "cvut:fel/libutilui" => "stx:libtool2"
+task "cvut:fel/libutilui" => "stx:libtool"
+
+task "jv:dart/compiler" => "stx:libbasic"
+
+task "stx:goodies/magritte" => "stx:libbasic"
+task "jv:libgdbs" => "stx:libbasic"
+task "jv:vdb" => "stx:libbasic"
+
+task "jv:cface" => "stx:libbasic"
+
+
+
+#clear "stx:projects/smalltalk" => "stx:libsvn"
+
+#define eXept repositories
+project :'exept:repositories' do
+  repository :'exept:cvs' do
+    type :cvs
+    url ":ext:vrany@dialin.exept.de:/cvs/stx"
+  end
+
+  repository :'exept:svn' do
+    type :svn
+    url "svn+ssh://vrany@dialin.exept.de/srv/svn/repositories"
+  end
+
+  repository :'exept:hgcvs' do
+    type :hgcvs
+    url "ssh://vrany@dialin.exept.de/srv/hg/repositories"
+  end
+end
+
+
+
+
+
+project :'jv' do
+  import :'stx:jv-branch'
+
+  import :'exept:repositories'
+  import :'expecco-sdk:repository2'
+
+  #import :'stx:regression'
+  import :'stx:libsvn2:reports'
+
+  package 'exept:smallTeam',:repository => :'exept:cvs'
+  #package 'stx:goodies/builder/reports',:repository => :'exept:cvs'
+
+
+  #package 'stx:libbasic', :repository => :'swing:hgsvn'
+  #package 'stx:libbasic3', :repository => :'swing:hgsvn'
+  #package 'stx:libtool', :repository => :'swing:hgsvn'
+
+
+  repository :swing
+
+  package 'stx:goodies/announcements'
+  package 'cvut:fel/libutilui'
+  package 'cvut:fel/perseus/core'
+  package 'cvut:fel/perseus/core_ui'
+  package 'cvut:fel/perseus/pascal', :branch => 'branches/IZAR-1.5.x'
+
+  package "jv:dart/compiler"
+
+  metacello_and_libscm_checkouter = Proc.new do | pkg, build_dir |
+    base = project.repository(pkg.repository).url
+    pkg_comps = pkg.name.sub(':', '/').split("/");
+    pkg_tail = pkg_comps.last
+    pkg_body = pkg_comps[0..(pkg_comps.size - 2)];
+    wc = build_dir / pkg.directory
+    FileUtils.mkdir_p(File.dirname(wc))
+    cmd = "svn co #{base}/#{pkg_body.join("/")}/#{pkg.branch == nil ? 'trunk' : pkg.branch}/#{pkg_tail} #{wc}"
+    puts "Issuing: #{cmd}"
+    if not system cmd
+      error "Cannot checkout #{pkg.name} using custom checkouter"
+    end
+  end
+
+  package 'stx:goodies/metacello/base', :checkout => metacello_and_libscm_checkouter
+  package 'stx:goodies/metacello/core', :checkout => metacello_and_libscm_checkouter
+  package 'stx:goodies/metacello/stx', :checkout => metacello_and_libscm_checkouter
+
+  package 'exept:regression', :repository => :'swing:baseline'
+
+  package 'stx:libwidg', :repository => :'swing:hg'
+
+
+  # SmallRuby fails to compile and run on Windows, sigh
+  if not win32?
+    # import :'cvut:smallruby:baseline'
+  end
+
+  tasks do
+    if not win32?
+        # task "stx:projects/smalltalk" => "cvut:smallruby/libcore"
+    end
+
+
+    task "stx:projects/smalltalk" => "cvut:fel/perseus/core"
+    task "stx:projects/smalltalk" => "cvut:fel/perseus/core_ui"
+    task "stx:projects/smalltalk" => "cvut:fel/perseus/pascal"
+
+    task "stx:projects/smalltalk" => "stx:goodies/cypress"
+    task "stx:projects/smalltalk" => "stx:goodies/metacello/base"
+    task "stx:projects/smalltalk" => "stx:goodies/metacello/core"
+    task "stx:projects/smalltalk" => "stx:goodies/metacello/stx"
+
+    task "stx:projects/smalltalk" => "stx:libscm/git"
+    task "stx:projects/smalltalk" => "stx:libscm/mercurial"
+  end
+
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/reports-libjava.rbspec	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,86 @@
+project :'stx:libjava:reports-common' do
+  import :'stx:jv-branch:for-reports-only'
+
+  tasks do
+
+    redefine BUILD_DIR / 'stx' / 'librun' => BUILD_DIR do | t |
+      checkout :'swing:private', 'stx/librun', :branch => 'branches/jv'
+    end
+
+
+    task :'test:pre' => [ BUILD_DIR / 'stx' / 'libjava' / 'tests' ,  ] do
+        chdir BUILD_DIR / 'stx' / 'libjava' / 'libs' / 'java' do
+      if win32? then
+         cmd = 'ant.bat'
+        else
+         cmd = 'ant'
+        end
+          if not system cmd
+            raise "Cannot run maven"
+          end
+        end
+    end
+
+    task :'install:jv:post' do
+      bld_dir = BUILD_DIR / 'stx' / 'libjava'
+      pkg_dir = $install_jv_dirs[:pkg_dir] / 'stx' / 'libjava'
+
+      cp_rx bld_dir / 'examples' ,  pkg_dir / 'examples' do | fname |
+        # fname is full path!!!
+        /\.svn|CVS|\.cvsignore|tests/.match(fname) == nil
+      end
+
+      mkdir pkg_dir / 'java'
+      cp_rx bld_dir / 'java' / 'libs' ,  pkg_dir /  'java' / 'libs' do | fname |
+        # fname is full path!!!
+        /\.svn|CVS|\.cvsignore|tests/.match(fname) == nil
+      end
+
+    end
+  end
+end
+
+project :'stx:libjava:reports' do
+  import :'stx:libjava:reports-common'
+  package 'stx:libjava', :test => true#, :lint => true
+end
+
+project :'stx:libjava:mauve' do
+  import :'stx:libjava:reports-common'
+  package 'stx:libjava/tests/mauve', :test => true
+end
+
+project :'stx:libjava:experiments:reports' do
+  import :'stx:libjava:reports-common'
+  package 'stx:libjava/experiments', :test => true, :lint => true
+end
+
+
+project :'stx:libjava:tools:reports' do
+  import :'stx:libjava:reports-common'
+  package 'stx:libjava/tools', :test => true, :lint => true
+end
+
+
+project :'stx:libjava:benchmarks' do
+  import :'stx:libjava:reports-common'
+  tasks do
+    task :'test:post' do
+      chdir BUILD_DIR / 'stx' / 'libjava' / 'benchmarks' / 'java' do
+        if not system 'ant'
+          raise Exception.new("Running benchmarks failed")
+        end
+      end
+
+      chdir BUILD_DIR / 'stx' / 'libjava' / 'benchmarks'  do
+        if not system 'rake'
+          raise Exception.new("Running benchmarks failed")
+        end
+      end
+    end
+  end
+end
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/reports-misc.rbspec	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,276 @@
+# This file contains various test projects
+
+project :'stx:libscm/git:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+
+  repository :'bitbucket:janvrany'
+
+  package 'stx:libscm/common', :test => true, :lint => true, :link => false
+  package 'stx:libscm/git', :test => true, :lint => true, :link => false
+
+end
+
+project :'stx:libscm/mercurial:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+  repository :'bitbucket:janvrany'
+  package 'stx:libscm'
+  package 'stx:libscm/common',    :link => false, :lint => true
+  package 'stx:libscm/mercurial', :link => false, :lint => true
+
+  tasks do
+    task :'test:post' => REPORT_DIR do
+	   setup = ''
+       if ENV['STX_LIBSCM_MERCURIAL_HG_VERSION'] != nil then
+	     hgversion = ENV['STX_LIBSCM_MERCURIAL_HG_VERSION']
+		 hgroot = ENV['STX_LIBSCM_MERCURIAL_HG_VERSIONS_ROOT']
+		 if hgroot == nil then
+		   raise Exception.new("STX_LIBSCM_MERCURIAL_HG_VERSION defined but not STX_LIBSCM_MERCURIAL_HG_VERSIONS_ROOT!")
+		 end
+		 hgdir = File.join(hgroot, hgversion)
+		 if win32?
+		   hgexe = "python #{hgroot}\\#{hgversion}\\Python27\\Scripts\\hg"
+		 else
+		   hgexe = File.join(hgroot, hgversion, 'usr', 'local', 'bin' , 'hg')
+		 end
+		 setup = "-S \"Class tryLocalSourceFirst: true. UserPreferences current hgCommand:'#{hgexe}'\""
+	   end
+
+       run_report(project.application, [ 'stx:libscm/mercurial' ], 'Builder::TestReport', setup, '--coverage  -I stx:libscm/common')
+	end
+  end
+
+end
+
+project :'stx:libscm/mercurial:reports:6.2.2' do
+  import :'stx:repositories'
+  import :'stx:6.2.2'
+
+  repository :'bitbucket:janvrany'
+  package 'stx:libscm'
+  package 'stx:libscm/common',    :link => false#, :test => true, :lint => true, :coverage => true # Coverage not suypported in 6.2.2
+  package 'stx:libscm/mercurial', :link => false, :test => true, :lint => true#, :coverage => true
+
+  # Little hack to enforce package compilation
+  tasks do
+    task :'compile:post' => [ :'stx:libscm/common' , :'stx:libscm/mercurial' ]
+  end
+
+end
+
+project :'stx:goodies/petitparser:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+  package 'stx:goodies/petitparser', :link => false, :test => true, :lint => true, :coverage => true
+  package 'stx:goodies/petitparser/analyzer', :link => false, :test => true, :lint => true, :coverage => true
+  package 'stx:goodies/petitparser/compiler/tests', :link => false, :test => true, :lint => true, :coverage => true
+  package 'stx:goodies/petitparser/parsers/smalltalk/tests', :link => false, :test => true, :lint => true, :coverage => true
+  package 'stx:goodies/petitparser/parsers/java', :link => false, :test => true, :lint => true, :coverage => true
+
+end
+
+project :'stx:regression' do
+  import :'stx:jv-branch:for-reports-only'
+
+  package 'exept:regression', :repository => :'swing:private:hg', :branch => 'jv', :test => true
+  package 'stx:libview/tests', :test => true
+
+  tasks do
+    task :'test:pre' => BUILD_DIR / 'goodies' / 'CharacterEncoderCodeGenerator.st'
+
+    file BUILD_DIR / 'goodies' / 'CharacterEncoderCodeGenerator.st' do
+        checkout(:'swing:baseline', 'stx/goodies/CharacterEncoderCodeGenerator.st')
+    end
+
+    task :'test:post' do
+      if not core_developer_machine?
+        rm_rf BUILD_DIR / 'exept' / 'regression'
+      end
+    end
+  end
+end
+
+project :'stx:goodies/refactoryBrowser/lint:reports' do
+  import :'stx:jv-branch:for-reports-only'
+  package "stx:goodies/refactoryBrowser/lint", :test => true, :lint =>  true
+end
+
+project :'stx:libsvn2:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+  # Manual checkouter, since libsvn2 is in libsvn repository...
+  checkouter = Proc.new do | pkg, build_dir |
+    base = project.repository(pkg.repository).url
+    repo = 'stx/libsvn'
+    wc = build_dir / pkg.directory
+    FileUtils.mkdir_p(File.dirname(wc))
+    if not system "svn co #{base}/#{repo}#{pkg.branch} #{wc}"
+      error "Cannot checkout stx:libsvn2"
+    end
+  end
+
+  package "stx:libsvn2",
+    :repository => :swing,
+    :branch => '/branches/libsvn2',
+    :checkout => checkouter,
+    :test => true, :lint => true, :link => false
+
+  tasks do
+    task 'stx:projects/smalltalk' => 'stx:libsvn2'
+    task 'stx:libsvn2' => 'stx:libbasic'
+  end
+
+end
+
+project :'jn:refactoring_custom:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+  repository :'bitbucket:jnesveda' do
+    type :hg
+    url "https://bitbucket.org/jnesveda"
+    separator '-'
+  end
+
+  # Manual checkouter
+  checkouter = Proc.new do | pkg, build_dir |
+    base = project.repository(pkg.repository).url
+    repo = 'refactoring_custom'
+    wc = build_dir / pkg.directory
+    FileUtils.mkdir_p(File.dirname(wc))
+    if not system "hg clone #{base}/#{repo} #{wc}"
+      error "Cannot checkout jn:refactoring_custom"
+    end
+  end
+
+
+  package "jn:refactoring_custom",
+    :repository => :'bitbucket:jnesveda', :test => true, :lint => true, :coverage => true, :link => false,   :checkout => checkouter
+
+  tasks do
+    task 'stx:projects/smalltalk' => 'jn:refactoring_custom'
+    task 'jn:refactoring_custom' => 'stx:libbasic'
+  end
+
+end
+
+project :'stx:goodies/smallsense:reports' do
+  import :'stx:jv-branch:for-reports-only'
+  package "stx:goodies/smallsense", :test => true, :lint => true, :coverage => true
+end
+
+project :'stx:goodies/sunit:reports' do
+  import :'stx:jv-branch:for-reports-only'
+  package "stx:goodies/sunit", :test => true, :lint => true, :coverage => true
+end
+
+
+
+project :'jv:calipel:s:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+  package 'jv:calipel', :repository => :'bitbucket:janvrany'
+  package "jv:calipel/s", :link => false
+  package "jv:calipel/s/stx", :link => false
+  package "jv:calipel/s/tests", :test => true, :lint => true, :link => false
+
+  tasks do
+    task 'stx:projects/smalltalk' => 'jv:calipel/s'
+    task 'stx:projects/smalltalk' => 'jv:calipel/s/stx'
+    task 'jv:calipel/s' => 'stx:libbasic'
+    task 'jv:calipel/s/stx' => 'stx:libbasic'
+  end
+
+end
+
+
+
+project :'xmlsuite:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+  repository :swing
+  package "stx:goodies/announcements"
+  package "cvut:fel/perseus/core"
+  package "cvut:fel/libutilui"
+  package "cvut:fel/perseus/core_ui"
+  package "stx:goodies/xmlsuite/core", :test => true, :lint =>  true
+  package "stx:goodies/xmlsuite/xmlreaderimpl", :test => true, :lint =>  true
+  package "stx:goodies/xmlsuite/xquery", :test => true, :lint =>  true
+
+  tasks do
+    task "stx:goodies/xmlsuite/xmlreaderimpl" => "stx:goodies/xmlsuite/core"
+    task "stx:goodies/xmlsuite/xquery" => [ "stx:goodies/xmlsuite/core" , "cvut:fel/perseus/core_ui" ]
+    task "stx:goodies/xmlsuite/core" => "cvut:fel/perseus/core"
+    task "cvut:fel/perseus/core" => "stx:goodies/announcements"
+
+    task 'stx:projects/smalltalk' => "stx:goodies/xmlsuite/core"
+    task 'stx:projects/smalltalk' => "stx:goodies/xmlsuite/xmlreaderimpl"
+    task 'stx:projects/smalltalk' => "stx:goodies/xmlsuite/xquery"
+
+  end
+end
+
+
+project :'xtreams:reports' do
+  import :'stx:jv-branch:for-reports-only'
+
+  checkouter = Proc.new do | pkg, build_dir |
+    base = project.repository(pkg.repository).url
+    repo = 'stx/goodies/xtreams'
+    repo_pkg = pkg.name[repo.size+1..pkg.name.size]
+    wc = build_dir / pkg.directory
+    url = "#{base}/#{repo}/#{pkg.branch || 'trunk'}/#{repo_pkg}"
+    FileUtils.mkdir_p(File.dirname(wc))
+    if not system "svn co #{url} #{wc}"
+      error "Cannot checkout xtreams: #{url}"
+    end
+  end
+
+  app_name "smalltalkx-jv-branch+xtreams"
+
+  repository :'swing:hg'
+
+  package "stx:goodies/xtreams"
+  package "stx:goodies/xtreams/support", :lint => true, :link => false
+  package "stx:goodies/xtreams/core", :lint => true, :link => false
+  package "stx:goodies/xtreams/core/tests", :link => false
+  package "stx:goodies/xtreams/substreams", :lint => true, :link => false
+  package "stx:goodies/xtreams/substreams/tests", :link => false
+  package "stx:goodies/xtreams/terminals", :lint => true, :link => false
+  package "stx:goodies/xtreams/terminals/tests", :link => false
+  package "stx:goodies/xtreams/transforms", :lint => true,  :link => false
+  package "stx:goodies/xtreams/transforms/tests", :link => false
+
+  tasks do
+    # Dependencies
+    task "stx:goodies/xtreams/support" => "stx:libbasic"
+    task "stx:goodies/xtreams/core" => "stx:goodies/xtreams/support"
+    task "stx:goodies/xtreams/substreams" => "stx:goodies/xtreams/core"
+    task "stx:goodies/xtreams/terminals" => "stx:goodies/xtreams/core"
+    task "stx:goodies/xtreams/transforms" => "stx:goodies/xtreams/core"
+
+    # Link dependencies
+    task 'stx:projects/smalltalk' => "stx:goodies/xtreams/core"
+    task 'stx:projects/smalltalk' => "stx:goodies/xtreams/terminals"
+    task 'stx:projects/smalltalk' => "stx:goodies/xtreams/substreams"
+    task 'stx:projects/smalltalk' => "stx:goodies/xtreams/transforms"
+
+    task :'dist:main' => :'dist:build-tree'
+
+    task 'test:post' => [ 'stx:goodies/builder/reports', REPORT_DIR ] do
+      app = project.application
+      packages = [
+        "stx:goodies/xtreams/support/tests" ,
+        "stx:goodies/xtreams/core/tests" ,
+        "stx:goodies/xtreams/substreams/tests" ,
+        "stx:goodies/xtreams/terminals/tests" ,
+        "stx:goodies/xtreams/transforms/tests" ,
+      ]
+      run_report(app, packages, 'Builder::TestReport')
+    end
+
+
+  end
+
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/stx-6.2.2.rbspec	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,46 @@
+load "baseline.deps.rake"
+
+project :'stx:6.2.2' do
+  # Builds (actually - downloads) official Smalltalk/X 6.2.2 released
+  # by eXept on July 2012.
+  # import :'stx:baseline'
+
+
+  tasks do
+    task :'checkout:buildtools'
+
+    task :'checkout:pre' => [ BUILD_DIR / 'stx' ]
+
+    file BUILD_DIR / 'stx' => [ BUILD_DIR ] do
+      # should download stuff from eXept site...
+      if win32? 
+      	files = [ 'win32.zip' ]
+      else 
+      	files = [ 'linux.tgz', 'common.tgz' ]
+      end
+
+      download_dir = (ENV['DOWNLOADS'] || BUILD_DIR) 
+
+      files.each do | f |
+        chdir download_dir do      	        
+          if not File.exist? f        	
+            if not system "wget ftp://ftp.exept.de/download/stx/stx622/#{f}"
+              raise Exception.new("Cannot download #{f}")
+            end  
+          end                      
+        end
+        chdir BUILD_DIR do
+          if win32? 
+            unpack = "unzip #{download_dir / f}"
+          else            
+            unpack = "tar xzf #{download_dir / f}"
+          end
+          if not system unpack  
+            raise Exception.new("Cannot unzip #{download_dir / f}")
+          end          	
+        end
+      end  
+    end
+  end
+end  
+  
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/stx-jv.rbspec	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,408 @@
+load "jv-branch.deps.rake"
+
+# Include Hudson build number of builded by Hudson"
+if ENV['BUILD_NUMBER']
+  build_id="build#{ENV['BUILD_NUMBER']}"
+else
+  build_id="#{Time.now.strftime("%Y%m%d")}"
+end
+
+project :'stx:jv-branch-core' do
+  # Core Smalltalk/X - does contain only standard libraries,
+  # and development tools. Does not contain any other 'features'
+  # like XML suite, Java support. Usable as a basis for standalone
+  # applications that needs some JV-branch features.
+  import :'stx:baseline'
+
+  # FORKED libraries
+  # ======================================================================
+  package "stx:libbasic", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libbasic2", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libbasic3", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libcomp", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libtool", :repository => :'swing:hg', :branch => 'jv'
+ 
+  package "stx:libview", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libview2", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libwidg", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libwidg2", :repository => :'swing:hg', :branch => 'jv'
+
+  package "stx:goodies/sunit", :repository => :'swing:hg'
+  package "stx:goodies/monticello", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:goodies/refactoryBrowser", :repository => :'swing:hg', :branch => 'jv'
+  package "stx:libsvn", :repository => :'swing:hg', :branch => 'jv'
+
+  # Some more development tools to build and preload
+  # ======================================================================
+  package "stx:goodies/xml/vw", :repository => :'swing:baseline'
+  
+  # SmallSense
+  package "stx:goodies/regex", :repository => :'swing:baseline'
+  package "stx:goodies/smallsense", :repository => :'bitbucket:janvrany'
+  package "stx:goodies/smallsense/refactoring_custom"
+
+  
+  tasks do
+    # Build and install documentation for stx:libjava and stx:libscm/mercurial
+
+    task "stx:libjava:post" do 
+      chdir BUILD_DIR / 'stx' / 'libjava' do
+        make "doc-install"
+      end
+    end
+
+    task "stx:libscm/mercurial:post" do 
+      chdir BUILD_DIR / 'stx' / 'libscm' / 'mercurial' do
+        make "doc-install"
+      end
+    end
+
+
+    redefine BUILD_DIR / 'stx' / 'stc' => BUILD_DIR do | t |
+      checkout :'swing:private:hg', 'stx/stc', :branch => 'jv'
+    end
+
+    redefine BUILD_DIR / 'stx' / 'librun' => BUILD_DIR do | t |
+      checkout :'swing:private:hg', 'stx/librun', :branch => 'jv'
+    end
+
+    if win32?
+
+
+      task :'checkout:post' do
+        rm_f BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp'
+      end
+
+      file BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp' do
+        cp BUILD_DIR / 'misc' / 'distutils' / 'src' / 'lib' / "splash-smalltalkx-#{project.app_version.split(".")[0..2].join(".")}.bmp",
+           BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp'
+      end
+
+      task "stx:projects/smalltalk" => BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp'
+
+    end
+
+    # Try execute run the VM if it starts up
+    task :'compile:post' do
+      if PROJECT == 'stx:jv-branch' then  
+        chdir BUILD_DIR / 'stx' / 'projects' / 'smalltalk' do
+          if win32?
+            cmd = "smalltalk.bat -I --quick --eval \"Stdout nextPutLine:'OKay, VM runs'. Smalltalk exit: 0\""
+          else
+            cmd = "./smalltalk -I --quick --eval \"Stdout nextPutLine:'OKay, VM runs'. Smalltalk exit: 0\""
+          end
+          if not system cmd
+            raise Exception.new("Cannot run smalltalk!")
+          end
+        end
+      end
+    end
+  
+  if (TOOLCHAIN == "mingw32" || TOOLCHAIN == 'mingw') then
+    task :'compile:post' => BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'libgcc_s_dw2-1.dll'
+    
+    file BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'libgcc_s_dw2-1.dll' do
+        cp ENV['MINGW_DIR'] / 'bin' / 'libgcc_s_dw2-1.dll' , BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'libgcc_s_dw2-1.dll'
+    end
+    end
+
+    # Build documentation for Mercurial & STX:LIBJAVA
+    task :'dist:pre' do
+        chdir (BUILD_DIR / 'stx' / 'libscm' / 'mercurial') do
+            make 'doc'
+            make 'doc-install'
+        end
+    end
+  
+  task :'stx:projects/smalltalk:pre' do   
+    chdir (BUILD_DIR / 'stx' / 'projects' / 'smalltalk') do         
+    # Hack for MINGW32 - must patch bc.mak ifdefs, sigh.
+    # use ruby instead of sed as ruby has to be installed anyway    
+    cmd = "ruby -ibkp -pe \"gsub /ifdef USEMINGW64/, 'if defined(USEMINGW64) || defined(USEMINGW32)'\" bc.mak"
+    #puts cmd
+    if not system(cmd)  then
+        raise Exception.new("Cannot patch bc.mak")
+    end      
+      end     
+  end
+
+    # Cross-compile hack for stx:libprofiler
+    if win32_wine?
+    task :'stx:libprofiler:pre' do
+      chdir (BUILD_DIR / 'stx' / 'libprofiler') do
+        sh "wine cmd /C config.bat"
+      end
+    end
+
+    task :'stx:projects/smalltalk:pre' do   
+      chdir (BUILD_DIR / 'stx' / 'projects' / 'smalltalk') do   
+        make "buildDate.h"    
+      end
+    end
+
+    task :'stx:goodies/xmlsuite/xmlreaderimpl:pre' do
+      chdir (BUILD_DIR / 'stx' / 'goodies' / 'xmlsuite' / 'xmlreaderimpl') do
+        [
+          'support' / 'expat-2.0.1' / 'bcb5' / 'release' /'obj' / 'xmlwf',
+          'support' / 'expat-2.0.1' / 'bcb5' / 'release' /'obj' / 'libexpat',
+          'support' / 'expat-2.0.1' / 'bcb5' / 'release' /'obj' / 'libexpatw',
+          'support' / 'expat-2.0.1' / 'bcb5' / 'release' /'obj' / 'libexpat_static',
+          'support' / 'expat-2.0.1' / 'bcb5' / 'release' /'obj' / 'libexpatw_static',
+          'support' / 'expat-2.0.1' / 'bcb5' / 'release' /'obj' / 'examples'
+        ].each do | f |
+          if not File.exists?(f)
+            mkdir_p f
+          end
+        end
+      end
+    end
+    end
+
+    # Hack for badly-named files in libtool
+    task :'stx:libtool:post' do
+      chdir (BUILD_DIR / 'stx' / 'libtool') do
+  # Windows does not support symlinks, copy the file
+  if win32?
+    if not File.exist? 'Tools_BrowserList.STH'
+      cp 'Tools__BrowserList.STH', 'Tools_BrowserList.STH'
+    end
+    if not File.exist? 'Tools_NavigatorModel.STH'
+      cp 'Tools__NavigatorModel.STH', 'Tools_NavigatorModel.STH'
+    end
+    if not File.exist? 'Tools_NavigationState.STH'
+      cp 'Tools__NavigationState.STH', 'Tools_NavigationState.STH'
+    end
+  else
+    if not File.exist? 'Tools_BrowserList.H'
+      ln_s 'Tools__BrowserList.H', 'Tools_BrowserList.H'
+    end
+    if not File.exist? 'Tools_NavigatorModel.H'
+      ln_s 'Tools__NavigatorModel.H', 'Tools_NavigatorModel.H'
+    end
+    if not File.exist? 'Tools_NavigationState.H'
+      ln_s 'Tools__NavigationState.H', 'Tools_NavigationState.H'
+    end
+  end
+      end
+    end
+  end
+
+end
+
+
+
+project :'stx:jv-branch' do
+  # Standard Smalltalk/X IDE with some nice libraries preloaded
+
+  import :'stx:jv-branch-core'
+
+
+  app_name "smalltalkx-jv-branch"
+  app_version "6.2.5.0_0"
+
+  # Forked PetitParser
+  package "stx:goodies/petitparser", :repository => :'bitbucket:janvrany', :link => false
+  package "stx:goodies/petitparser/tests", :link => false
+  package "stx:goodies/petitparser/analyzer",  :link => false
+  package "stx:goodies/petitparser/analyzer/tests",  :link => false
+
+  # Monticello
+  package "stx:libcompat", :repository => :'swing:baseline'
+  package "stx:goodies/communication", :repository => :'swing:baseline'
+
+  # Profiler
+  package "stx:libprofiler", :repository => :'swing'
+
+  # Java support
+  package "stx:libjava", :repository => :'bitbucket:janvrany'
+  package "stx:libjava/tools"
+  package "stx:libjava/experiments"
+  #package "stx:libjava/examples" :link => false
+
+  # Smalltalk/X IDE
+  application 'stx:projects/smalltalk', :repository => :'swing:hg', :branch => 'jv'
+
+  if (ENV['USER'] == 'builder') || ( ENV['USER'] == 'vranyj1')  || (ENV['USERNAME'] == 'builder') || ( ENV['USERNAME'] == 'vranyj1') then
+     stx_libjava_checkouter =
+         Proc.new do | pkg, build_dir |
+             repo = :'swing:hg'
+             puts "Checking out #{pkg.name} from #{repo} (cache / staging repo)..."
+             checkout repo, pkg.directory, :branch => pkg.branch, :package => pkg, :separator => '.'
+             puts "Checking out #{pkg.name} from #{repo} (cache)...done"
+
+             File.open(build_dir / 'stx' / 'libjava' / '.hg' / 'hgrc' , 'w') do | f |
+                 f.puts "[paths]"
+                 f.puts "default = https://bitbucket.org/janvrany/stx-libjava"
+             end
+
+             repo = pkg.repository
+             puts "Checking out #{pkg.name} from #{repo}..."
+             update repo, pkg.directory, :branch => pkg.branch, :package => pkg, :separator => pkg._separator
+             puts "Checking out #{pkg.name} from #{repo}...done"
+         end
+
+     stx_libjava_updater =
+         Proc.new do | pkg, build_dir |
+             repo = :'swing:hg'
+             puts "Updating #{pkg.name} from #{repo} (cache / staging repo)..."
+             update repo, pkg.directory, :branch => pkg.branch, :package => pkg, :separator => '.'
+             puts "Checking out #{pkg.name} from #{repo} (cache)...done"
+
+             repo = pkg.repository
+             puts "Checking out #{pkg.name} from #{repo}..."
+             update repo, pkg.directory, :branch => pkg.branch, :package => pkg, :separator => pkg._separator
+             puts "Checking out #{pkg.name} from #{repo}...done"
+         end
+
+
+     package "stx:libjava", :checkout => stx_libjava_checkouter, :update => stx_libjava_updater
+  end
+
+
+  # Other nice packages...
+  metacello_and_libscm_checkouter = Proc.new do | pkg, build_dir |
+    base = project.repository(pkg.repository).url
+    pkg_comps = pkg.name.sub(':', '/').split("/");
+    pkg_tail = pkg_comps.last
+    pkg_body = pkg_comps[0..(pkg_comps.size - 2)];
+    wc = build_dir / pkg.directory
+    FileUtils.mkdir_p(File.dirname(wc))
+    cmd = "svn co #{base}/#{pkg_body.join("/")}/#{pkg.branch == nil ? 'trunk' : pkg.branch}/#{pkg_tail} #{wc}"
+    puts "Issuing: #{cmd}"
+    if not system cmd
+      error "Cannot checkout #{pkg.name} using custom checkouter"
+    end
+  end
+
+
+  package 'stx:libscm', :repository => :'bitbucket:janvrany'
+  package 'stx:libscm/common', :repository => :'bitbucket:janvrany'
+  package 'stx:libscm/mercurial', :repository => :'bitbucket:janvrany'
+  package 'stx:libscm/mercurial/monticello', :repository => :'bitbucket:janvrany'
+  package 'stx:goodies/ring', :repository => :'bitbucket:janvrany', :link => false
+  package 'stx:goodies/libcairo', :repository => :'bitbucket:janvrany', :link => false
+  package 'stx:goodies/cypress', :repository => :'bitbucket:janvrany'
+  package "stx:goodies/xmlsuite", :repository => :'bitbucket:janvrany'  
+  package "stx:goodies/loggia", :repository => :'swing:baseline'
+  package 'stx:goodies/smaCC',:repository => :'swing'
+  package "squeak:graphviz",  :repository => :'swing'  
+
+  #package "stx:goodies/builder/reports", :repository => :'swing:baseline', :link => false
+
+
+
+  tasks do
+    task "stx:projects/smalltalk" => "stx:libwebkit"
+    task "stx:projects/smalltalk" => "stx:libjava"
+    task "stx:projects/smalltalk" => "stx:libjava/tools"
+    task "stx:projects/smalltalk" => "stx:libjava/experiments"
+    #task "stx:libjava/examples" => "stx:libjava"
+    #task "stx:projects/smalltalk" => "stx:libjava/examples"
+    task 'stx:projects/smalltalk' => 'stx:goodies/loggia'
+    task 'stx:projects/smalltalk' => 'stx:goodies/monticello'
+    task 'stx:projects/smalltalk' => 'stx:goodies/cypress'
+    task 'stx:projects/smalltalk' => 'stx:libscm/mercurial'
+    task 'stx:projects/smalltalk' => 'stx:libscm/mercurial/monticello'
+    task 'stx:projects/smalltalk' => 'stx:goodies/builder/reports'
+    task 'stx:projects/smalltalk' => 'stx:goodies/ring'
+    task 'stx:projects/smalltalk' => 'stx:goodies/libcairo'
+    task "stx:goodies/builder/reports" => 'stx:libbasic'
+
+    task :'dist:main' => :'dist:build-tree'
+    task :'dist:main' => :'dist:jv-branch'
+
+
+
+    task :'dist:jv:pre' => :'stx:jv-branch:extractver'
+
+    if win32?     	
+			app_name    = project.app_name      || (raise Exception.new("No app_name property specified"))
+	    app_version = project.app_version   || (raise Exception.new("No app_version property specified"))
+	    version = app_version.split('_').first
+
+	    install_dir = DIST_DIR / 'dist' / "#{app_name}-#{app_version}_#{ARCH}-#{PLATFORM}"
+	    bin_dir = install_dir / 'bin'
+
+	    cairo_dll_dir = nil
+    	cairo_dlls = nil
+    	if ARCH == 'i386'
+    		cairo_dll_dir = BUILD_DIR / 'stx' / 'goodies' / 'libcairo' / 'support' / 'win32' / 'i586'
+	      cairo_dlls =  [ 
+	      	'libcairo-2.dll' ,
+					'libfontconfig-1.dll' ,
+					'libfreetype-6.dll' ,
+					'liblzma-5.dll' ,
+					'libpixman-1-0.dll' ,
+					'libpng15-15.dll' ,
+					'libxml2-2.dll' ,
+					'zlib1.dll'
+					]
+			else
+				cairo_dll_dir = BUILD_DIR / 'stx' / 'goodies' / 'libcairo' / 'support' / 'win32' / 'x86_64'
+				cairo_dlls =  [ 
+	      	'fontconfig.dll' ,
+	      	'iconv.dll' ,
+	      	'libcairo-2.dll' ,
+	      	'libpng16.dll' ,
+	      	'libxml2.dll' ,
+	      	'pixman-1.dll' ,
+	      	'zlib1.dll'
+	      ]
+			end
+
+    	task :'dist:jv:post' => :'dist:jv:variables'
+    	cairo_dlls.each do | dll |
+    		task :'dist:jv:post' => bin_dir / dll
+				file bin_dir / dll do
+					mkdir_p bin_dir
+					cp cairo_dll_dir / dll , bin_dir / dll
+				end
+    	end
+    end
+
+    task :'dist:jv-branch' => [ :'dist:jv:all',
+                                :'dist:jv:archive',
+                                # Documentation
+                                :'dist:jv:doc' ,
+                                :'dist:jv:archive-doc' ]
+
+  end
+end
+
+task :'stx:jv-branch:extractver' do
+  ver = nil
+  if win32?
+    stx_exe = 'stx.com'
+  else
+    stx_exe = './stx'
+  end
+  chdir BUILD_DIR / 'stx' / 'projects' / 'smalltalk' do
+    ver = %x(#{stx_exe} --eval "Stdout nextPutAll: Smalltalk versionString")
+    if $?.exitstatus != 0
+      raise Exception.new("Failed extract version from stx")
+    end
+  end
+  ver = (ver.split(".")[0..2]).join(".")
+  project.app_version "#{ver}_#{build_id}"
+end
+
+
+project :'stx:jv-branch:for-reports-only' do
+  import :'stx:jv-branch'
+
+  tasks do
+    task :'stx:projects/smalltalk:pre' do
+      chdir BUILD_DIR / 'stx' / 'projects' / 'smalltalk' do
+         if win32?
+           system "bmake clobber"
+         else
+           system "make clobber"
+         end
+      end
+    end
+
+    clear :'dist:main' => :'dist:build-tree'
+    clear :'dist:main' => :'dist:jv-branch'
+  end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/specs/to.rbspec	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,87 @@
+
+load 'external/smallruby+to/package.deps.rake'
+
+task 'stx:projects/smalltalk' => 'cvut:smallruby/libcore' 
+task 'stx:projects/smalltalk' => 'jv:experiments/translucent'
+
+# Dependency of jv:experiments/translucent
+task 'jv:experiments/translucent' => 'stx:libbasic'
+task 'jv:experiments/translucent' => 'stx:libbasic2'
+task 'jv:experiments/translucent' => 'stx:libjava'
+task 'jv:experiments/translucent' => 'stx:goodies/webServer'
+task 'jv:experiments/translucent' => 'stx:goodies/communication'
+
+project :'stx:jv-branch+to' do
+  import :'stx:jv-branch'
+
+  # Include Hudson build number of builded by Hudson"
+  if ENV['BUILD_NUMBER'] 
+    build_id="build#{ENV['BUILD_NUMBER']}"
+  else
+    build_id="#{Time.now.strftime("%Y%m%d")}"
+  end
+
+  app_name "smalltalkx-jv-branch+to"
+  app_version "6.2.2_#{build_id}"
+  
+  #We can use default libcomp for now
+  #package "stx:libcomp", :repository => :'swing', :branch => 'branches/to'
+
+  #Do not run tests as they are really costly
+  #JK: I want it to be sure, that Java is working in TO 
+  #package "stx:libjava", :test => false
+
+  repository :'swing:baseline'
+  package "stx:goodies/regex"
+  package "stx:goodies/authentication"
+  package "stx:goodies/webServer"
+
+  repository :'swing'
+  package "cvut:stx/goodies/newcompiler"  
+  package 'cvut:smallruby/libcompiler', :branch => 'branches/to'
+  package 'cvut:smallruby/libcore', :branch => 'branches/translucent-objects'
+  package 'jv:experiments/translucent', :test => true;
+
+  # Java support
+  package "squeak:petitparser", :repository => :'swing'
+  package "stx:libjava", :repository => :'swing', :branch => 'branches/jk_new_structure/src'
+  package "stx:libjava/tools", :repository => :'swing', :branch => 'branches/jk_new_structure/src'
+  package "stx:libjava/experiments", :repository => :'swing', :branch => 'branches/jk_new_structure/src'
+
+  
+  tasks do 
+
+    # We don't neeed special STC (for now ... changing STC is HELL of a task 
+    #redefine BUILD_DIR / 'stx' / 'stc' => BUILD_DIR do | t |
+    #  checkout :'swing:private', 'stx/stc', :branch => 'branches/to'
+    #end
+   
+    # We don't need special librun (for now ... maybe in future, JInterpret)
+    #redefine BUILD_DIR / 'stx' / 'librun' => BUILD_DIR do | t |
+    #  checkout :'swing:private', 'stx/librun', :branch => 'branches/to'
+    #end
+
+
+    if win32?    
+      task :'checkout:post' do		
+        rm_f BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp'
+      end
+      
+      file BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp' do
+        cp BUILD_DIR / 'misc' / 'distutils' / 'src' / 'lib' / 'splash-smalltalkx-6.1.2.bmp',
+        BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp'
+      end
+
+      task "stx:projects/smalltalk" => BUILD_DIR / 'stx' / 'projects' / 'smalltalk' / 'stx_splash.bmp'
+
+    end
+
+    # do not create jv dist archive
+    redefine :'dist:main' => :'dist:build-tree'
+     
+  end
+end
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/dsl_tests.rb	Sun May 22 00:32:07 2016 +0100
@@ -0,0 +1,45 @@
+require File.join(File.dirname(__FILE__), '..' , 'rakelib' , 'dsl')
+require 'test/unit'
+
+module Rake::StX::DSL
+  class ObjectTests < Test::Unit::TestCase
+
+    class A < Object
+      property :bar
+      property :baz, :default => false, :values => [true, false]
+      property :qux, :default => (Proc.new do 
+                                   :qux
+                                 end)      
+    end
+    
+    def test_01           
+      f = A.new()
+      assert f.bar == nil
+      f.bar "baz"
+      assert f.bar == "baz"
+      f.bar = "qux"
+      assert f.bar == "qux"
+    end
+
+    def test_02
+      f = A.new()     
+      assert f.baz == false
+      f.baz true
+      assert f.baz == true
+      gote = false
+      begin
+        f.baz "String"
+      rescue Exception 
+        gote = true
+      end
+      assert gote
+      
+    end
+    
+    def test_03
+      f = A.new()
+      assert f.qux.kind_of?  Proc        
+      assert f.qux.call() == :qux      
+    end
+  end
+end