Merge jv
authorHG Automerge
Thu, 05 Jan 2017 21:02:10 +0000
branchjv
changeset 21249 86c01ee5a76e
parent 21248 2346b1744906 (current diff)
parent 21219 31ce02101bb7 (diff)
child 21250 f856fbfcdc60
Merge
AbstractOperatingSystem.st
Autoload.st
Collection.st
Date.st
Infinity.st
Make.proto
Make.spec
NonPositionableExternalStream.st
OSProcess.st
Object.st
PipeStream.st
RecursionLock.st
Semaphore.st
Smalltalk.st
SomeNumber.st
UnixOperatingSystem.st
Win32OperatingSystem.st
abbrev.stc
bc.mak
libInit.cc
stx_libbasic.st
--- a/AbstractOperatingSystem.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/AbstractOperatingSystem.st	Thu Jan 05 21:02:10 2017 +0000
@@ -903,16 +903,6 @@
 
 !AbstractOperatingSystem class methodsFor:'executing OS commands-implementation'!
 
-exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork newPgrp:newGrp inDirectory:aDirectory
-    "execute an OS command"
-
-    ^ self 
-        exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork 
-        newPgrp:newGrp inDirectory:aDirectory showWindow:false
-
-    "Created: / 12.11.1998 / 14:46:15 / cg"
-!
-
 exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork 
                   newPgrp:newGrp inDirectory:aDirectory showWindow:showWindowBooleanOrNil
     "execute an OS command"
@@ -941,243 +931,206 @@
 !
 
 startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-    errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment inDirectory:dir
+    errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
+    environment:anEvironmentDictionary inDirectory:dir newPgrp:newPgrp showWindow:showWindowBooleanOrNil
 
     "start executing the OS command as specified by the argument, aCommandString
      as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
-     The command gets stdIn, stdOut and stdErr assigned from the arguments;
-     each may be nil.
-     Return the processId if successful, nil otherwise.
-     Use #monitorPid:action: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-    "raise an error: must be redefined in concrete subclass(es)"
-
-    ^ self 
-        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-        errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil 
-        environment:environment inDirectory:dir
-        showWindow:nil
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-    errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment 
-    inDirectory:dir newPgrp:newPgrp showWindow:showWindowBooleanOrNil
-
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
-     The command gets stdIn, stdOut and stdErr assigned from the arguments;
-     each may be nil.
-     Return the processId if successful, nil otherwise.
-     Use #monitorPid:action: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-    "raise an error: must be redefined in concrete subclass(es)"
-
-    ^ self subclassResponsibility
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-    errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment 
-    inDirectory:dir showWindow:showWindowBooleanOrNil
-
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+     If aCommandString is a String, the commandString is passed to a shell for execution
+     - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
+     If aCommandString is an Array, the first element is the command to be executed,
+     and the other elements are the arguments to the command. No shell is invoked in this case.
      The command gets stdIn, stdOut and stdErr assigned from the arguments;
      each may be nil.
      Return the processId if successful, nil otherwise.
      Use #monitorPid:action: for synchronization and exec status return,
      or #killProcess: to stop it."
 
-    "raise an error: must be redefined in concrete subclass(es)"
-
-    ^ self
-        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-        errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment 
-        inDirectory:dir newPgrp:true showWindow:showWindowBooleanOrNil
-
-    "Modified: / 08-11-2016 / 21:24:27 / cg"
-! !
-
-!AbstractOperatingSystem class methodsFor:'executing OS commands-private'!
-
-shuffleAllFrom:anInStream to:anOutStream lineWise:lineWise lockWith:aLock
-
-    lineWise ifFalse:[
-	^ anInStream copyToEndInto:anOutStream.
+    |nullStream in out err shellAndArgs rslt auxFd|
+
+    aCommandString isNil ifTrue:[^ nil].
+
+    (in := anExternalInStream) isNil ifTrue:[
+        nullStream := Filename nullDevice readWriteStream.
+        in := nullStream.
+    ].
+    (out := anExternalOutStream) isNil ifTrue:[
+        nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
+        out := nullStream.
+    ].
+    (err := anExternalErrStream) isNil ifTrue:[
+        err := out
+    ].
+    anAuxiliaryStream notNil ifTrue:[
+        auxFd := anAuxiliaryStream fileHandle.
     ].
-    [anInStream isOpen and:[anInStream atEnd not]] whileTrue:[
-	aLock critical:[
-	    self
-		shuffleFrom:anInStream
-		to:anOutStream
-		lineWise:lineWise
-	]
-    ]
-!
-
-shuffleFrom:anInStream to:anOutStream lineWise:lineWise
-    "copy data from anInStream to anOutStream.
-     Caller makes sure, than anInStream does not block.
-     anOutstream should have been set to non-blocking-mode"
-
-    lineWise ifTrue:[
-	|data|
-
-	data := anInStream nextLine.
-	data notNil ifTrue:[
-	    anOutStream nextPutLine:data
-	] .
-    ] ifFalse:[
-	anInStream copyToEndInto:anOutStream.
+
+    shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
+
+    rslt := self
+        exec:(shellAndArgs at:1)
+        withArguments:(shellAndArgs at:2)
+        environment:anEvironmentDictionary
+        fileDescriptors:(Array with:in fileHandle
+                               with:out fileHandle
+                               with:err fileHandle
+                               with:auxFd)
+        fork:true
+        newPgrp:newPgrp
+        inDirectory:dir
+        showWindow:(showWindowBooleanOrNil ? (shellAndArgs at:3)).
+
+    nullStream notNil ifTrue:[
+        nullStream close.
     ].
-!
-
-shuffleRestFrom:anInStream to:anOutStream lineWise:lineWise
-    [anInStream atEnd] whileFalse:[
-	self
-	    shuffleFrom:anInStream
-	    to:anOutStream
-	    lineWise:lineWise.
-    ].
-!
-
-startProcess:aCommandString
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual.
-     Return the processId if successful, nil otherwise.
-     Use #waitForProcess: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-    ^ self
-	startProcess:aCommandString
-	inputFrom:nil
-	outputTo:nil
-	errorTo:nil
-	auxFrom:nil
-	inDirectory:nil
-
-    "
-     |pid|
-
-     pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
-     (Delay forSeconds:3) wait.
-     OperatingSystem killProcess:pid.
-    "
-    "
-     |pid|
-
-     pid := OperatingSystem startProcess:'dir/l'.
-     (Delay forSeconds:1) wait.
-     OperatingSystem killProcess:pid.
-    "
-    "
-     |pid|
-
-     pid := OperatingSystem
-		startProcess:'dir/l'
-		inputFrom:nil
-		outputTo:Stdout
-		errorTo:nil
-		inDirectory:nil.
-     (Delay forSeconds:2) wait.
-     OperatingSystem killProcess:pid.
-    "
+
+    ^ rslt
+
+    "blocking at current prio (i.e. only higher prio threads execute):
+
+     OperatingSystem executeCommand:'ls -l > out'.
+     OperatingSystem executeCommand:#('/bin/ls' '-l') outputTo:Transcript.
+    "
+
+    "non-blocking (lower prio threads continue):
+
+     |in out err pid sema|
+
+     in := 'out' asFilename readStream.
+     out := 'out2' asFilename writeStream.
+     err := 'err' asFilename writeStream.
+
+     sema := Semaphore new.
+     pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
+
+     The following will no longer work. monitorPid has disappeared
+
+     pid notNil ifTrue:[
+         Processor monitorPid:pid action:[:osStatus | sema signal ].
+     ].
+     in close.
+     out close.
+     err close.
+     sema wait.
+     Transcript showCR:'finished'
+    "
+
+    "
+     |pid sema|
+
+     sema := Semaphore new.
+
+     Processor
+            monitor:[
+                pid := OperatingSystem startProcess:'(sleep 2; ls -l) > out 2>err'
+            ]
+            action:[:osStatus | sema signal ].
+
+     sema wait.
+     Transcript showCR:'finished'
+    "
+
+    "
+     |pid sema|
+
+     sema := Semaphore new.
+
+     Processor
+            monitor:[
+                pid := OperatingSystem startProcess:'(sleep 1; echo 1; sleep 9; ls -l) > out 2>err'
+            ]
+            action:[:osStatus | sema signal ].
+
+     Delay waitForSeconds:2.
+     OperatingSystem terminateProcess:pid.
+     Transcript showCR:'terminated'
+    "
+
+    "======================== WINDOWS: ==================================================================="
+
+     "blocking at current prio (i.e. only higher prio threads execute):
+
+     OperatingSystem executeCommand:'dir > out'.
+     OperatingSystem executeCommand:'tree /A' outputTo:Transcript.
+     OperatingSystem executeCommand:#('c:\windows\system32\tree.com' '/A' '/F') outputTo:Transcript.
+     OperatingSystem executeCommand:#('c:\windows\system32\where.exe' '/T' '*.dll') outputTo:Transcript.
+    "
+
+    "non-blocking (lower prio threads continue):
+
+     |in out err pid sema|
+
+     in := 'out' asFilename readStream.
+     out := 'out2' asFilename writeStream.
+     err := 'err' asFilename writeStream.
+
+     sema := Semaphore new.
+     pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
+
+     The following will no longer work. monitorPid has disappeared
+
+     pid notNil ifTrue:[
+         Processor monitorPid:pid action:[:OSstatus | sema signal ].
+     ].
+     in close.
+     out close.
+     err close.
+     sema wait.
+     Transcript showCR:'finished'
+    "
+
+    "
+     |pid sema|
+
+     sema := Semaphore new.
+
+     Processor
+            monitor:[
+                pid := OperatingSystem startProcess:'dir > out 2>err'
+            ]
+            action:[:osStatus | sema signal ].
+
+     sema wait.
+     Transcript showCR:'finished'
+    "
+
+"<<END
+     |pid sema|
+
+     sema := Semaphore new.
+
+     Processor
+            monitor:[
+                pid := OperatingSystem startProcess:'(echo 1 & stx --eval "Delay waitForSeconds:100" & dir) >out' withCRs
+            ]
+            action:[:osStatus | sema signal ].
+
+     Delay waitForSeconds:5.
+     OperatingSystem terminateProcessGroup:pid.
+     Transcript showCR:'terminated'
+END"
+
+"<<END
+     |pid sema|
+
+     sema := Semaphore new.
+
+     Processor
+            monitor:[
+                pid := OperatingSystem startProcess:{ 'C:\Users\cg\work\stx\projects\smalltalk\stx.com' . '--eval' . '"Delay waitForSeconds:100"' }
+            ]
+            action:[:osStatus | sema signal ].
+
+     Delay waitForSeconds:5.
+     OperatingSystem terminateProcess:pid.
+     Transcript showCR:'terminated'
+END"
+
 
     "Modified: / 21.3.1997 / 10:04:35 / dq"
-    "Modified: / 10.11.1998 / 21:03:50 / cg"
-!
-
-startProcess:aCommandString inDirectory:aDirectory
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual.
-     Return the processId if successful, nil otherwise.
-     Use #waitForProcess: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-    ^ self
-	startProcess:aCommandString
-	inputFrom:nil
-	outputTo:nil
-	errorTo:nil
-	auxFrom:nil
-	inDirectory:aDirectory
-    "
-     |pid|
-
-     pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
-     (Delay forSeconds:3) wait.
-     OperatingSystem killProcess:pid.
-    "
-
-    "Modified: / 21.3.1997 / 10:04:35 / dq"
-    "Modified: / 28.1.1998 / 14:13:33 / md"
-    "Modified: / 10.11.1998 / 20:59:33 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
-     The command gets stdIn, stdOut and stdErr assigned from the arguments;
-     each may be nil.
-     Return the processId if successful, nil otherwise.
-     Use #monitorPid:action: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-     ^ self
-	startProcess:aCommandString
-	inputFrom:anExternalInStream
-	outputTo:anExternalOutStream
-	errorTo:anExternalErrStream
-	auxFrom:nil
-	inDirectory:nil
-
-    "Modified: / 10.11.1998 / 20:59:05 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-    errorTo:anExternalErrStream auxFrom:anAuxiliaryStream inDirectory:dir
-
-    ^ self
-	startProcess:aCommandString
-	inputFrom:anExternalInStream
-	outputTo:anExternalOutStream
-	errorTo:anExternalErrStream
-	auxFrom:anAuxiliaryStream
-	environment:nil
-	inDirectory:dir
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream inDirectory:dir
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     The commandString is passed to a shell for execution - see the description of
-     'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
-     The command gets stdIn, stdOut and stdErr assigned from the arguments;
-     each may be nil.
-     Return the processId if successful, nil otherwise.
-     Use #monitorPid:action: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-    ^ self
-	startProcess:aCommandString
-	inputFrom:anExternalInStream
-	outputTo:anExternalOutStream
-	errorTo:anExternalErrStream
-	auxFrom:nil
-	inDirectory:dir
+    "Modified: / 15.7.1997 / 16:03:51 / stefan"
+    "Modified: / 5.6.1998 / 19:03:51 / cg"
+    "Created: / 12.11.1998 / 14:39:20 / cg"
 ! !
 
 !AbstractOperatingSystem class methodsFor:'executing OS commands-public'!
@@ -1467,258 +1420,24 @@
         This argument is ignored on Unix systems.
         See examples below."
 
-    |pid exitStatus sema pIn pOut pErr pAux externalInStream externalOutStream externalErrStream externalAuxStream
-     shuffledInStream shuffledOutStream shuffledErrStream shuffledAuxStream
-     inputShufflerProcess outputShufflerProcess errorShufflerProcess auxShufflerProcess stopShufflers
-     inStreamToClose outStreamToClose errStreamToClose auxStreamToClose nullStream terminateLock
-     closeStreams|
-
-    terminateLock := Semaphore forMutualExclusion.
-    ((externalInStream := anInStream) notNil
-     and:[externalInStream isExternalStream not]) ifTrue:[
-        pIn := NonPositionableExternalStream makePipe.
-        inStreamToClose := externalInStream := pIn at:1.
-        shuffledInStream := pIn at:2.
-        anInStream isBinary ifTrue:[
-            shuffledInStream binary
-        ].
-        lineWise ifFalse:[
-            shuffledInStream blocking:false.
-        ].
-
-        "/ start a reader process, shuffling data from the given
-        "/ inStream to the pipe (which is connected to the commands input)
-        inputShufflerProcess :=
-            [
-                [
-                    [anInStream atEnd] whileFalse:[
-                        self shuffleFrom:anInStream to:shuffledInStream lineWise:lineWise.
-                        shuffledInStream flush
-                    ]
-                ] ensure:[
-                    shuffledInStream close
-                ]
-            ] newProcess
-                name:'cmd input shuffler';
-"/                beSystemProcess;
-                resume.
-    ].
-    ((externalOutStream := anOutStream) notNil
-     and:[externalOutStream isExternalStream not]) ifTrue:[
-        pOut := NonPositionableExternalStream makePipe.
-        shuffledOutStream := (pOut at:1).
-        anOutStream isBinary ifTrue:[
-            shuffledOutStream binary
-        ].
-        outStreamToClose := externalOutStream := pOut at:2.
-        outputShufflerProcess :=
-            [
-                WriteError handle:[:ex |
-                    "/ ignored
-                ] do:[
-                    self shuffleAllFrom:shuffledOutStream to:anOutStream lineWise:lineWise lockWith:terminateLock.
-                ].
-            ] newProcess
-                priority:(Processor userSchedulingPriority "+ 1");
-                name:'cmd output shuffler';
-"/                beSystemProcess;
-                resume.
-    ].
-    (externalErrStream := anErrStream) notNil ifTrue:[
-        anErrStream == anOutStream ifTrue:[
-            externalErrStream := externalOutStream
-        ] ifFalse:[
-            anErrStream isExternalStream ifFalse:[
-                pErr := NonPositionableExternalStream makePipe.
-                shuffledErrStream := (pErr at:1).
-                anErrStream isBinary ifTrue:[
-                    shuffledErrStream binary
-                ].
-                errStreamToClose := externalErrStream := pErr at:2.
-                errorShufflerProcess :=
-                    [
-                        self shuffleAllFrom:shuffledErrStream to:anErrStream lineWise:lineWise lockWith:terminateLock.
-                    ] newProcess
-                        priority:(Processor userSchedulingPriority + 1);
-                        name:'cmd err-output shuffler';
-"/                        beSystemProcess;
-                        resume.
-            ]
-        ]
-    ].
-    ((externalAuxStream := anAuxStream) notNil
-     and:[externalAuxStream isExternalStream not]) ifTrue:[
-        pAux := NonPositionableExternalStream makePipe.
-        auxStreamToClose := externalAuxStream := pAux at:1.
-        shuffledAuxStream := pAux at:2.
-        shuffledAuxStream blocking:false.
-        anAuxStream isBinary ifTrue:[
-            shuffledAuxStream binary
+        |osProcess|
+
+        osProcess := OSProcess new
+            command:aCommandStringOrArray;
+            inStream:anInStream;
+            outStream:anOutStream;
+            errorStream:anErrStream;
+            auxStream:anAuxStream;
+            environment:environmentDictionary;
+            directory:dirOrNil;
+            lineWise:lineWise;
+            showWindow:showWindowBooleanOrNil.
+
+        osProcess execute ifFalse:[
+            aBlock value:osProcess exitStatus.
+            ^ false.
         ].
-
-        "/ start a reader process, shuffling data from the given
-        "/ auxStream to the pipe (which is connected to the commands aux)
-        auxShufflerProcess :=
-            [
-                [
-                    [anAuxStream atEnd] whileFalse:[
-                        self shuffleFrom:anAuxStream to:shuffledAuxStream lineWise:false.
-                        shuffledAuxStream flush
-                    ]
-                ] ensure:[
-                    shuffledAuxStream close
-                ]
-            ] newProcess
-                name:'cmd aux shuffler';
-"/                beSystemProcess;
-                resume.
-    ].
-
-    stopShufflers := [:shuffleRest |
-            inputShufflerProcess notNil ifTrue:[
-                terminateLock critical:[inputShufflerProcess terminate].
-                inputShufflerProcess waitUntilTerminated
-            ].
-            auxShufflerProcess notNil ifTrue:[
-                terminateLock critical:[auxShufflerProcess terminate].
-                auxShufflerProcess waitUntilTerminated
-            ].
-            outputShufflerProcess notNil ifTrue:[
-                terminateLock critical:[outputShufflerProcess terminate].
-                outputShufflerProcess waitUntilTerminated.
-                shuffleRest ifTrue:[ self shuffleRestFrom:shuffledOutStream to:anOutStream lineWise:lineWise ].
-                shuffledOutStream close.
-            ].
-            errorShufflerProcess notNil ifTrue:[
-                terminateLock critical:[errorShufflerProcess terminate].
-                errorShufflerProcess waitUntilTerminated.
-                shuffleRest ifTrue:[ self shuffleRestFrom:shuffledErrStream to:anErrStream lineWise:lineWise ].
-                shuffledErrStream close.
-            ].
-        ].
-
-    closeStreams := [
-            inStreamToClose notNil ifTrue:[
-                inStreamToClose close
-            ].
-            errStreamToClose notNil ifTrue:[
-                errStreamToClose close
-            ].
-            outStreamToClose notNil ifTrue:[
-                outStreamToClose close
-            ].
-            auxStreamToClose notNil ifTrue:[
-                auxStreamToClose close
-            ].
-            nullStream notNil ifTrue:[
-                nullStream close
-            ].
-        ].
-
-
-    sema := Semaphore new name:'OS command wait'.
-    [
-        externalInStream isNil ifTrue:[
-            externalInStream := nullStream := Filename nullDevice readWriteStream.
-        ].
-        externalOutStream isNil ifTrue:[
-            nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
-            externalOutStream := nullStream.
-        ].
-        externalErrStream isNil ifTrue:[
-            externalErrStream := externalOutStream
-        ].
-
-        pid := Processor
-                    monitor:[
-                        self
-                            startProcess:aCommandStringOrArray
-                            inputFrom:externalInStream
-                            outputTo:externalOutStream
-                            errorTo:externalErrStream
-                            auxFrom:externalAuxStream
-                            environment:environmentDictionary
-                            inDirectory:dirOrNil
-                            newPgrp:newPgrp
-                            showWindow:showWindowBooleanOrNil
-                    ]
-                    action:[:status |
-                        status stillAlive ifFalse:[
-                            exitStatus := status.
-                            sema signal.
-                            self closePid:pid
-                        ]
-                    ].
-
-        pid isNil ifTrue:[
-            exitStatus := self osProcessStatusClass processCreationFailure
-        ] ifFalse:[
-            sema wait.
-        ].
-    ] ifCurtailed:[
-        closeStreams value.
-        pid notNil ifTrue:[
-            "/ terminate the os-command (and all of its forked commands)
-            self terminateProcessGroup:pid.
-            self terminateProcess:pid.
-            self closePid:pid.
-        ].
-        stopShufflers value:false.
-    ].
-
-    closeStreams value.
-    stopShufflers value:true.
-    (exitStatus isNil or:[exitStatus success]) ifFalse:[
-        ^ aBlock value:exitStatus
-    ].
-    ^ true
-
-    "
-        |outStream errStream|
-
-        outStream := '' writeStream.
-
-        OperatingSystem executeCommand:'ls -l'
-                        inputFrom:'abc' readStream
-                        outputTo:outStream
-                        errorTo:nil
-                        inDirectory:nil
-                        lineWise:true
-                        onError:[:exitStatus | ^ false].
-        outStream contents
-    "
-
-    "
-        |outStream errStream|
-
-        outStream := #[] writeStream.
-
-        OperatingSystem executeCommand:'cat'
-                        inputFrom:(ByteArray new:5000000) readStream
-                        outputTo:outStream
-                        errorTo:nil
-                        inDirectory:nil
-                        lineWise:false
-                        onError:[:exitStatus | ^ false].
-        outStream size
-    "
-
-    "
-        |outStream errStream|
-
-        outStream := '' writeStream.
-
-        OperatingSystem executeCommand:'gpg -s --batch --no-tty --passphrase-fd 0 /tmp/passwd'
-                        inputFrom:'bla' readStream
-                        outputTo:outStream
-                        errorTo:nil
-                        inDirectory:nil
-                        lineWise:true
-                        onError:[:exitStatus |  false].
-        outStream contents
-    "
-
-    "Modified: / 11-02-2007 / 20:54:39 / cg"
+        ^ true.
 !
 
 executeCommand:aCommandStringOrArray inputFrom:anInStream outputTo:anOutStream
@@ -2780,12 +2499,11 @@
     "return true, if the OS can execute aCommand.
      For now, this only works with UNIX."
 
-    |fn fullPath|
-
-    fullPath := (self pathOfCommand:aCommandString).
+    |fullPath|
+
+    fullPath := self pathOfCommand:aCommandString.
     fullPath isNil ifTrue:[^ false].
-    fn := fullPath asFilename.
-    ^ fn exists and:[fn isExecutableProgram].
+    ^ fullPath asFilename isExecutableProgram.
 
     "
      OperatingSystem canExecuteCommand:'fooBar'
@@ -2847,12 +2565,12 @@
 
     path := self pathOfCommand:(self nameOfSTXExecutable).
     path isNil ifTrue:[
-	'./stx' asFilename exists ifTrue:[
-	    path := './stx'
-	].
-    ].
-    path isNil ifTrue:[
-	 'OperatingSystem [warning]: cannot figure out my executable''s path' infoPrintCR.
+        './stx' asFilename exists ifTrue:[
+            path := './stx'
+        ].
+        path isNil ifTrue:[
+             'OperatingSystem [warning]: cannot figure out my executable''s path' infoPrintCR.
+        ].
     ].
     ^ path
 
@@ -2866,6 +2584,7 @@
 !AbstractOperatingSystem class methodsFor:'executing OS commands-wrappers'!
 
 exec:aCommandPath withArguments:argArray
+    <resource: #obsolete>
     "execute the OS command specified by the argument, aCommandPath, with
      arguments in argArray (no arguments, if nil).
      If successful, this method does NOT return and smalltalk is gone.
@@ -2873,56 +2592,71 @@
      Can be used on UNIX with fork or on other systems to chain to another program."
 
     ^ self
-	exec:aCommandPath
-	withArguments:argArray
-	environment:nil
-	fileDescriptors:#(0 1 2)
-	fork:false
-	newPgrp:false
-	inDirectory:nil
+        exec:aCommandPath
+        withArguments:argArray
+        environment:nil
+        fileDescriptors:#(0 1 2)
+        fork:false
+        newPgrp:false
+        inDirectory:nil
+        showWindow:false
 
     "/ never reached ...
 
     "Modified: / 12.11.1998 / 14:44:26 / cg"
 !
 
+exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork newPgrp:newGrp inDirectory:aDirectory
+    <resource: #obsolete>
+    "execute an OS command"
+
+    ^ self 
+        exec:aCommandPath withArguments:argArray environment:env fileDescriptors:fds fork:doFork 
+        newPgrp:newGrp inDirectory:aDirectory showWindow:false
+
+    "Created: / 12.11.1998 / 14:46:15 / cg"
+!
+
 exec:aCommandPath withArguments:argArray fileDescriptors:fileDescriptors fork:doFork newPgrp:newPgrp inDirectory:aDirectory
+    <resource: #obsolete>
     ^ self
-	exec:aCommandPath
-	withArguments:argArray
-	environment:nil
-	fileDescriptors:fileDescriptors
-	fork:doFork
-	newPgrp:newPgrp
-	inDirectory:aDirectory
+        exec:aCommandPath
+        withArguments:argArray
+        environment:nil
+        fileDescriptors:fileDescriptors
+        fork:doFork
+        newPgrp:newPgrp
+        inDirectory:aDirectory
+        showWindow:false
 !
 
 exec:aCommandPath withArguments:argArray fork:doFork
+    <resource: #obsolete>
     "execute an OS command without I/O redirection.
      The command reads its input and writes its output
      from/to whatever terminal device ST/X was started
      (typically, the terminal window)"
 
     ^ self
-	exec:aCommandPath
-	withArguments:argArray
-	environment:nil
-	fileDescriptors:#(0 1 2)
-	fork:doFork
-	newPgrp:false
-	inDirectory:nil
-
+        exec:aCommandPath
+        withArguments:argArray
+        environment:nil
+        fileDescriptors:#(0 1 2)
+        fork:doFork
+        newPgrp:false
+        inDirectory:nil
+        showWindow:false
     "
      |id|
 
      id := OperatingSystem fork.
      id == 0 ifTrue:[
-	'I am the child'.
-	OperatingSystem
-	    exec:'/bin/ls'
-	    withArguments:#('ls' '/tmp')
-	    fork:false.
-	'not reached'.
+        'I am the child'.
+        OperatingSystem
+            exec:'/bin/ls'
+            withArguments:#('ls' '/tmp')
+            fork:false.
+        'not reached'.
      ]
     "
 
@@ -2931,12 +2665,12 @@
 
      id := OperatingSystem fork.
      id == 0 ifTrue:[
-	'I am the child'.
-	OperatingSystem
-	    exec:'/bin/sh'
-	    withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
-	    fork:false.
-	'not reached'.
+        'I am the child'.
+        OperatingSystem
+            exec:'/bin/sh'
+            withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
+            fork:false.
+        'not reached'.
      ].
      id printNL.
      (Delay forSeconds:3.5) wait.
@@ -2950,31 +2684,32 @@
 !
 
 exec:aCommandPath withArguments:argArray fork:doFork inDirectory:aDirectory
+    <resource: #obsolete>
     "execute an OS command without I/O redirection.
      The command reads its input and writes its output
      from/to whatever terminal device ST/X was started
      (typically, the terminal window)"
 
     ^ self
-	exec:aCommandPath
-	withArguments:argArray
-	environment:nil
-	fileDescriptors:#(0 1 2)
-	fork:doFork
-	newPgrp:false
-	inDirectory:aDirectory
-
+        exec:aCommandPath
+        withArguments:argArray
+        environment:nil
+        fileDescriptors:#(0 1 2)
+        fork:doFork
+        newPgrp:false
+        inDirectory:aDirectory
+        showWindow:false
     "
      |id|
 
      id := OperatingSystem fork.
      id == 0 ifTrue:[
-	'I am the child'.
-	OperatingSystem
-	    exec:'/bin/ls'
-	    withArguments:#('ls' '/tmp')
-	    fork:false.
-	'not reached'.
+        'I am the child'.
+        OperatingSystem
+            exec:'/bin/ls'
+            withArguments:#('ls' '/tmp')
+            fork:false.
+        'not reached'.
      ]
     "
 
@@ -2983,12 +2718,12 @@
 
      id := OperatingSystem fork.
      id == 0 ifTrue:[
-	'I am the child'.
-	OperatingSystem
-	    exec:'/bin/sh'
-	    withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
-	    fork:false.
-	'not reached'.
+        'I am the child'.
+        OperatingSystem
+            exec:'/bin/sh'
+            withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2')
+            fork:false.
+        'not reached'.
      ].
      id printNL.
      (Delay forSeconds:3.5) wait.
@@ -3003,6 +2738,7 @@
 !
 
 exec:aCommandPath withArguments:argArray showWindow:showWindowBooleanOrNil
+    <resource: #obsolete>
     "execute the OS command specified by the argument, aCommandPath, with
      arguments in argArray (no arguments, if nil).
      If successful, this method does NOT return and smalltalk is gone.
@@ -3022,6 +2758,116 @@
     "/ never reached ...
 
     "Modified: / 12.11.1998 / 14:44:26 / cg"
+!
+
+startProcess:aCommandString
+    <resource: #obsolete>
+
+    ^ self 
+        startProcess:aCommandString inputFrom:nil outputTo:nil
+        errorTo:nil auxFrom:nil environment:nil 
+        inDirectory:nil newPgrp:true showWindow:nil
+
+    "
+     |pid|
+
+     pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
+     (Delay forSeconds:3) wait.
+     OperatingSystem killProcess:pid.
+    "
+    "
+     |pid|
+
+     pid := OperatingSystem startProcess:'dir/l'.
+     (Delay forSeconds:1) wait.
+     OperatingSystem killProcess:pid.
+    "
+    "
+     |pid|
+
+     pid := OperatingSystem
+                startProcess:'dir/l'
+                inputFrom:nil
+                outputTo:Stdout
+                errorTo:nil
+                inDirectory:nil.
+     (Delay forSeconds:2) wait.
+     OperatingSystem killProcess:pid.
+    "
+
+    "Modified: / 21.3.1997 / 10:04:35 / dq"
+    "Modified: / 10.11.1998 / 21:03:50 / cg"
+!
+
+startProcess:aCommandString inDirectory:aDirectory
+    <resource: #obsolete>
+
+    ^ self
+        startProcess:aCommandString inputFrom:nil outputTo:nil
+        errorTo:nil auxFrom:nil environment:nil 
+        inDirectory:aDirectory newPgrp:true showWindow:nil
+    "
+     |pid|
+
+     pid := OperatingSystem startProcess:'sleep 2; echo 1; sleep 2; echo 2'.
+     (Delay forSeconds:3) wait.
+     OperatingSystem killProcess:pid.
+    "
+
+    "Modified: / 21.3.1997 / 10:04:35 / dq"
+    "Modified: / 28.1.1998 / 14:13:33 / md"
+    "Modified: / 10.11.1998 / 20:59:33 / cg"
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream
+    <resource: #obsolete>
+
+    ^ self 
+        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+        errorTo:anExternalErrStream auxFrom:nil environment:nil 
+        inDirectory:nil newPgrp:true showWindow:nil
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+    errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment inDirectory:dir
+    <resource: #obsolete>
+
+    ^ self 
+        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+        errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment 
+        inDirectory:dir newPgrp:true showWindow:nil
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+    errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment 
+    inDirectory:dir showWindow:showWindowBooleanOrNil
+    <resource: #obsolete>
+
+    ^ self
+        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+        errorTo:anExternalErrStream auxFrom:anExternalAuxStreamOrNil environment:environment 
+        inDirectory:dir newPgrp:true showWindow:showWindowBooleanOrNil
+
+    "Modified: / 08-11-2016 / 21:24:27 / cg"
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+    errorTo:anExternalErrStream auxFrom:anAuxiliaryStream inDirectory:dir
+    <resource: #obsolete>
+
+    ^ self 
+        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+        errorTo:anExternalErrStream auxFrom:nil environment:nil
+        inDirectory:dir newPgrp:true showWindow:nil
+!
+
+startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream errorTo:anExternalErrStream inDirectory:dir
+    <resource: #obsolete>
+
+    ^ self
+        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
+        errorTo:anExternalErrStream auxFrom:nil environment:nil 
+        inDirectory:dir newPgrp:true showWindow:nil
 ! !
 
 !AbstractOperatingSystem class methodsFor:'file access'!
--- a/Autoload.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Autoload.st	Thu Jan 05 21:02:10 2017 +0000
@@ -172,12 +172,12 @@
 
     nameSymbol := aClassName asSymbol.
     (Smalltalk at:nameSymbol) isNil ifTrue:[
-	cls := Autoload 
-		subclass:nameSymbol
-		instanceVariableNames:''
-		classVariableNames:''
-		poolDictionaries:''
-		category:aCategory.
+        cls := self 
+                subclass:nameSymbol
+                instanceVariableNames:''
+                classVariableNames:''
+                poolDictionaries:''
+                category:aCategory.
     ].
     ^ cls
 
--- a/Collection.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Collection.st	Thu Jan 05 21:02:10 2017 +0000
@@ -343,6 +343,7 @@
     ^ self
 ! !
 
+
 !Collection methodsFor:'Compatibility-ANSI'!
 
 identityIncludes:anObject
@@ -1650,6 +1651,12 @@
 
 !
 
+asCollectionDo:aBlock
+    "enumerate myself"
+
+    self do:aBlock
+!
+
 asDictionary
     "return a Dictionary with the receiver collection's elements,
      using the original keys of the receiver as dictionary key.
--- a/Date.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Date.st	Thu Jan 05 21:02:10 2017 +0000
@@ -375,17 +375,17 @@
     |weekDayOfJan4 dayInYear year|
 
     year := yearArg.
-    weekDayOfJan4 := (Date  year:year month:1 day:4) dayInWeek.
+    weekDayOfJan4 := (self year:year month:1 day:4) dayInWeek.
     dayInYear := (week * 7) + dayInWeek - (weekDayOfJan4 + 3).
     dayInYear < 1 ifTrue:[
-        dayInYear := dayInYear + (Date daysInYear:year-1).
+        dayInYear := dayInYear + (self daysInYear:year-1).
         year := year - 1.
     ].
-    dayInYear > (Date daysInYear:year) ifTrue:[
-        dayInYear := dayInYear - (Date daysInYear:year).
+    dayInYear > (self daysInYear:year) ifTrue:[
+        dayInYear := dayInYear - (self daysInYear:year).
         year := year + 1.
     ].
-    ^ Date newDay:dayInYear year:year.
+    ^ self newDay:dayInYear year:year.
 
     "
      Date newDayInWeek:6 week:39 year:2008     
@@ -532,14 +532,14 @@
         ].
 
         dayOfYear notNil ifTrue:[
-            monthAndDay := Date monthAndDayFromDayInYear:dayOfYear forYear:year.
+            monthAndDay := self monthAndDayFromDayInYear:dayOfYear forYear:year.
             month := (monthAndDay at:1).
             day := (monthAndDay at:2).  
         ].
         
         day isNil ifTrue:[ day := 1 ].
         month isNil ifTrue:[ month := 1 ].
-        year isNil ifTrue:[ year := Date today year ].
+        year isNil ifTrue:[ year := self today year ].
 
         (year between:0 and:99) ifTrue:[
             year := UserPreferences current twoDigitDateHandler value:year.
@@ -736,7 +736,7 @@
     "return a date, representing tomorrow.
      See also: Time now / Timestamp now."
 
-    ^ Date today addDays:1
+    ^ self today addDays:1
 
     "
      Date tomorrow 
@@ -812,7 +812,7 @@
     "return a date, representing yesterday.
      See also: Time now / Timestamp now."
 
-    ^ Date today subtractDays:1
+    ^ self today subtractDays:1
 
     "
      Date yesterday 
@@ -925,6 +925,7 @@
     "
 ! !
 
+
 !Date class methodsFor:'change & update'!
 
 update:something with:aParameter from:changedObject
@@ -1132,7 +1133,7 @@
     |day dayInWeekOf1stJan firstThursday firstDayInWeek|
 
     "/ find the first thursday ...
-    day := Date newDay:1 year:aYear.
+    day := self newDay:1 year:aYear.
     dayInWeekOf1stJan := day dayInWeek.
     dayInWeekOf1stJan > 4 ifTrue:[
         firstThursday := day addDays:(4 - dayInWeekOf1stJan + 7).
@@ -1570,7 +1571,7 @@
     numDays < 0 ifTrue:[
         "/ not in a week here ...
         "/ can be either 52 or 53, depending on the previous year.
-        ^ self weekInYearOf:(Date year:date year - 1  month:12 day:31) 
+        ^ self weekInYearOf:(self year:date year - 1  month:12 day:31) 
     ].
 
     "/ compute the week 
@@ -1896,6 +1897,7 @@
     "Modified: 8.10.1996 / 19:25:39 / cg"
 ! !
 
+
 !Date class methodsFor:'private'!
 
 dayAbbrevsForLanguage:languageOrNilForDefault
@@ -2022,13 +2024,13 @@
     ].
     (format sameAs:'monthName') ifTrue:[
         monthName := string.
-        month := (Date monthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
+        month := (self monthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
 "/        month == 0 ifTrue:[self error:'invalid month name'].
         ^ #month -> month
     ].
     (format sameAs:'shortMonthName') ifTrue:[
         monthName := string.
-        month := (Date abbreviatedMonthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
+        month := (self abbreviatedMonthNamesForLanguage:languageOrNil) findFirst:[:m | monthName sameAs:m].
 "/        month == 0 ifTrue:[self error:'invalid month name'].
         ^ #month -> month
     ].
@@ -2112,6 +2114,7 @@
     "
 ! !
 
+
 !Date methodsFor:'Compatibility-ANSI'!
 
 dayOfWeek
@@ -2756,7 +2759,7 @@
 daysInMonth
     "return the number of days in the month of the receiver"
 
-    ^ Date daysInMonth:(self month) forYear:(self year)
+    ^ self class daysInMonth:(self month) forYear:(self year)
 
     "
      Date today daysInMonth
@@ -2766,7 +2769,7 @@
 daysInYear
     "return the number of days in the year of the receiver"
 
-    ^ Date daysInYear:(self year)
+    ^ self class daysInYear:(self year)
 
     "
      Date today daysInYear
@@ -2788,7 +2791,7 @@
      Today is excluded from the count (i.e. in a non-leap-year,
      the first january will return 364)"
 
-    ^ (Date daysInYear:(self year)) - self dayOfYear
+    ^ (self class daysInYear:(self year)) - self dayOfYear
 
     "
      Date today daysLeftInYear             
@@ -2798,7 +2801,7 @@
 isLeapYear
     "return true, if the receiver's year is a leap year"
 
-    ^ Date leapYear:(self year)
+    ^ self class leapYear:self year
 
     "
      Date today isLeapYear
@@ -3022,7 +3025,7 @@
                     - (self month * 100) "in the line above the new month is already completely calculated. So subtract the current month"
                     - self day  "in the line below the new day is already completely calculated. So subtract the current day"
                     + (self day min: self daysInMonth). "the new day considering the maximum number of days in the new month."
-    ^ Date 
+    ^ self class 
         year: newEncoding // 10000
         month: (newEncoding // 100 \\ 100) 
         day: newEncoding \\ 100. 
@@ -3120,7 +3123,7 @@
         month := (12 - (monthNegated \\ 12)).
     ].
 
-    ^ Date  year:year month:month day:1.
+    ^ self class year:year month:month day:1.
 
     "
      (Date newDay:3 month:6 year:2009) firstDayInMonth     
@@ -3171,7 +3174,7 @@
 
     "/ the argument must understand year, month and day to be
     "/ comparable, whatever it is
-    ^ dateEncoding < (Date encodeYear:aDate year month:aDate month day:aDate day)
+    ^ dateEncoding < (self class encodeYear:aDate year month:aDate month day:aDate day)
 
     "
         Date today < (Date day:24 month:12 year:2000)
@@ -3212,7 +3215,7 @@
 
     "/ the argument must understand year, month and day,
     "/ to be comparable, whatever it is
-    ^ dateEncoding > (Date encodeYear:aDate year month:aDate month day:aDate day)
+    ^ dateEncoding > (self class encodeYear:aDate year month:aDate month day:aDate day)
 
     "
       Date today > (Date newDay:24 month:12 year:2099)
@@ -3271,6 +3274,7 @@
 ! !
 
 
+
 !Date methodsFor:'obsolete'!
 
 asAbsoluteTime
@@ -3341,6 +3345,7 @@
     ^ self addDays:days
 ! !
 
+
 !Date methodsFor:'printing & storing'!
 
 addPrintBindingsTo:aDictionary
@@ -3442,7 +3447,7 @@
     aDictionary at:#week put:wsPadded0.
     aDictionary at:#Week put:ws.
 
-    year ~~ Date today year ifTrue:[
+    year ~~ self class today year ifTrue:[
         aDictionary at:#yearOrTime put:(' ' , year printString).
     ].
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/EventSemaphore.st	Thu Jan 05 21:02:10 2017 +0000
@@ -0,0 +1,170 @@
+"
+ COPYRIGHT (c) 2016 by eXept Sofware AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.  This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+"{ Package: 'stx:libbasic' }"
+
+"{ NameSpace: Smalltalk }"
+
+Semaphore subclass:#EventSemaphore
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'Kernel-Processes'
+!
+
+!EventSemaphore class methodsFor:'documentation'!
+
+copyright
+"
+ COPYRIGHT (c) 2016 by eXept Sofware AG
+              All Rights Reserved
+
+ This software is furnished under a license and may be used
+ only in accordance with the terms of that license and with the
+ inclusion of the above copyright notice.  This software may not
+ be provided or otherwise made available to, or used by, any
+ other person.  No title to or ownership of the software is
+ hereby transferred.
+"
+!
+
+documentation
+"
+    Processes wait for an EventSemaphores until it is signaled.
+    The EventSemaphore is not consumed and remains signaled until manually reset.
+
+    [author:]
+        Stefan Vogel
+
+    [see also:]
+        Semaphore
+"
+!
+
+example
+"
+    Create an event and signal it.
+    After being signaled waiter on the event return immediately.
+
+                                [exBegin]
+    |event|
+
+    event := EventSemaphore new.
+    [ event wait. Transcript showCR:'Process 1 continued' ] forkAt:9.
+    [ event wait. Transcript showCR:'Process 2 continued' ] forkAt:9.
+    event signal.
+    event wait.
+    event wait.
+                                [exEnd]
+"
+! !
+
+!EventSemaphore class methodsFor:'signaling'!
+
+new:n
+    "count must be 0 or 1"
+
+    (n == 0 or:[n == 1]) ifTrue:[
+        self new:n.
+    ].
+    ^ self error:'invalid count'.
+! !
+
+!EventSemaphore methodsFor:'blocked'!
+
+signalForAll
+    "blocked, since it would only set the event if there was anyone waiting"
+
+    ^ self shouldNotImplement.
+!
+
+signalIf
+    "blocked, since it would only set the event if there was anyone waiting"
+
+    ^ self shouldNotImplement.
+!
+
+waitWithTimeoutMs:milliSeconds state:waitStateSymbol
+    "blocked, since we had to re-implement it here"
+
+   ^ self shouldNotImplement
+! !
+
+!EventSemaphore methodsFor:'misc'!
+
+reset
+    "reset the event to the non-signaled state"
+
+    count := 0
+! !
+
+!EventSemaphore methodsFor:'semaphoreSet interface'!
+
+checkAndAddWaitingProcess:process
+    "interface for SemaphoreSet.
+     If the semaphore is available, return true.
+     Otherwise register our process to be wakened up once the semaphore is available
+     and return false.
+     ATTENTION: this must be invoked with OperatingSystem-interrupts-blocked.
+    "
+
+    count > 0 ifTrue:[
+        ^ true
+    ].
+    (waitingProcesses notNil and:[(waitingProcesses includesIdentical:process)]) ifFalse:[
+        self addWaitingProcess:process.
+    ].
+    ^ false
+
+    "Modified: / 14-12-1995 / 10:32:17 / stefan"
+    "Modified: / 11-08-2011 / 14:36:20 / cg"
+! !
+
+!EventSemaphore methodsFor:'signaling'!
+
+signal
+    "redefined to limit count to 1"
+
+    self signalOnce.
+! !
+
+!EventSemaphore methodsFor:'waiting'!
+
+wait
+    "once signaled, do not decrement the count"
+
+    self waitUncounted
+!
+
+waitWithTimeoutMs:milliSeconds
+    "wait for the semaphore, but abort the wait after some time.
+     return the receiver if the semaphore triggered normal, nil if we return
+     due to a timeout.
+     With zero timeout, this can be used to poll a semaphore (returning
+     the receiver if the semaphore is available, nil if not).
+     However, polling is not the intended use of semaphores, though.
+     If milliSeconds is nil, wait without timeout.
+
+     Redefined: once signaled, do not decrement the count"
+
+    ^ self waitUncountedWithTimeoutMs:milliSeconds.
+! !
+
+!EventSemaphore class methodsFor:'documentation'!
+
+version
+    ^ '$Header$'
+!
+
+version_CVS
+    ^ '$Header$'
+! !
+
--- a/Infinity.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Infinity.st	Thu Jan 05 21:02:10 2017 +0000
@@ -316,6 +316,13 @@
     ^ self negated
 !
 
+equalFromSomeNumber:aNumber
+    "Sent from aNumber = self, if aNumber does not know how to handle this.
+     Return true if aNumber = self."
+
+    ^ aNumber isInfinite and:[self sign == aNumber sign]
+!
+
 lessFromSomeNumber:aNumber
     "Sent from aNumber < self, if aNumber does not know how to handle this.
      Return true if aNumber < self."
--- a/Make.proto	Wed Dec 28 22:58:47 2016 +0000
+++ b/Make.proto	Thu Jan 05 21:02:10 2017 +0000
@@ -211,6 +211,7 @@
 $(OUTDIR)CompiledCode.$(O) CompiledCode.$(C) CompiledCode.$(H): CompiledCode.st $(INCLUDE_TOP)/stx/libbasic/ExecutableFunction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)ControlInterrupt.$(O) ControlInterrupt.$(C) ControlInterrupt.$(H): ControlInterrupt.st $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)Date.$(O) Date.$(C) Date.$(H): Date.st $(INCLUDE_TOP)/stx/libbasic/Magnitude.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)EventSemaphore.$(O) EventSemaphore.$(C) EventSemaphore.$(H): EventSemaphore.st $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/Semaphore.$(H) $(STCHDR)
 $(OUTDIR)Exception.$(O) Exception.$(C) Exception.$(H): Exception.st $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)ExternalFunction.$(O) ExternalFunction.$(C) ExternalFunction.$(H): ExternalFunction.st $(INCLUDE_TOP)/stx/libbasic/ExecutableFunction.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
 $(OUTDIR)False.$(O) False.$(C) False.$(H): False.st $(INCLUDE_TOP)/stx/libbasic/Boolean.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
@@ -508,10 +509,10 @@
 $(OUTDIR)UnderflowError.$(O) UnderflowError.$(C) UnderflowError.$(H): UnderflowError.st $(INCLUDE_TOP)/stx/libbasic/ArithmeticError.$(H) $(INCLUDE_TOP)/stx/libbasic/Error.$(H) $(INCLUDE_TOP)/stx/libbasic/Exception.$(H) $(INCLUDE_TOP)/stx/libbasic/ExecutionError.$(H) $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProceedableError.$(H) $(INCLUDE_TOP)/stx/libbasic/RangeError.$(H) $(STCHDR)
 $(OUTDIR)ZeroDivide.$(O) ZeroDivide.$(C) ZeroDivide.$(H): ZeroDivide.st $(INCLUDE_TOP)/stx/libbasic/ArithmeticError.$(H) $(INCLUDE_TOP)/stx/libbasic/DomainError.$(H) $(INCLUDE_TOP)/stx/libbasic/Error.$(H) $(INCLUDE_TOP)/stx/libbasic/Exception.$(H) $(INCLUDE_TOP)/stx/libbasic/ExecutionError.$(H) $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProceedableError.$(H) $(STCHDR)
 $(OUTDIR)BadRomanNumberFormatError.$(O) BadRomanNumberFormatError.$(C) BadRomanNumberFormatError.$(H): BadRomanNumberFormatError.st $(INCLUDE_TOP)/stx/libbasic/ConversionError.$(H) $(INCLUDE_TOP)/stx/libbasic/Error.$(H) $(INCLUDE_TOP)/stx/libbasic/Exception.$(H) $(INCLUDE_TOP)/stx/libbasic/GenericException.$(H) $(INCLUDE_TOP)/stx/libbasic/NumberConversionError.$(H) $(INCLUDE_TOP)/stx/libbasic/NumberFormatError.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/ProceedableError.$(H) $(INCLUDE_TOP)/stx/libbasic/RomanNumberFormatError.$(H) $(STCHDR)
-$(OUTDIR)UnixFileDescriptorHandle.$(O) UnixFileDescriptorHandle.$(C) UnixFileDescriptorHandle.$(H): UnixFileDescriptorHandle.st $(STCHDR)
-$(OUTDIR)UnixFileHandle.$(O) UnixFileHandle.$(C) UnixFileHandle.$(H): UnixFileHandle.st $(STCHDR)
-$(OUTDIR)UnixOperatingSystem.$(O) UnixOperatingSystem.$(C) UnixOperatingSystem.$(H): UnixOperatingSystem.st $(STCHDR)
-$(OUTDIR)OSXOperatingSystem.$(O) OSXOperatingSystem.$(C) OSXOperatingSystem.$(H): OSXOperatingSystem.st $(STCHDR)
+$(OUTDIR)UnixFileDescriptorHandle.$(O) UnixFileDescriptorHandle.$(C) UnixFileDescriptorHandle.$(H): UnixFileDescriptorHandle.st $(INCLUDE_TOP)/stx/libbasic/ExternalAddress.$(H) $(INCLUDE_TOP)/stx/libbasic/OSFileHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/OSHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)UnixFileHandle.$(O) UnixFileHandle.$(C) UnixFileHandle.$(H): UnixFileHandle.st $(INCLUDE_TOP)/stx/libbasic/ExternalAddress.$(H) $(INCLUDE_TOP)/stx/libbasic/OSFileHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/OSHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(STCHDR)
+$(OUTDIR)UnixOperatingSystem.$(O) UnixOperatingSystem.$(C) UnixOperatingSystem.$(H): UnixOperatingSystem.st $(INCLUDE_TOP)/stx/libbasic/AbstractOperatingSystem.$(H) $(INCLUDE_TOP)/stx/libbasic/ExternalAddress.$(H) $(INCLUDE_TOP)/stx/libbasic/OSFileHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/OSHandle.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/SharedPool.$(H) $(STCHDR)
+$(OUTDIR)OSXOperatingSystem.$(O) OSXOperatingSystem.$(C) OSXOperatingSystem.$(H): OSXOperatingSystem.st $(INCLUDE_TOP)/stx/libbasic/AbstractOperatingSystem.$(H) $(INCLUDE_TOP)/stx/libbasic/Object.$(H) $(INCLUDE_TOP)/stx/libbasic/UnixOperatingSystem.$(H) $(STCHDR)
 
 # ENDMAKEDEPEND --- do not remove this line
 
--- a/Make.spec	Wed Dec 28 22:58:47 2016 +0000
+++ b/Make.spec	Thu Jan 05 21:02:10 2017 +0000
@@ -121,6 +121,7 @@
 	CompiledCode \
 	ControlInterrupt \
 	Date \
+	EventSemaphore \
 	Exception \
 	ExternalFunction \
 	False \
@@ -511,6 +512,7 @@
     $(OUTDIR_SLASH)CompiledCode.$(O) \
     $(OUTDIR_SLASH)ControlInterrupt.$(O) \
     $(OUTDIR_SLASH)Date.$(O) \
+    $(OUTDIR_SLASH)EventSemaphore.$(O) \
     $(OUTDIR_SLASH)Exception.$(O) \
     $(OUTDIR_SLASH)ExternalFunction.$(O) \
     $(OUTDIR_SLASH)False.$(O) \
--- a/NonPositionableExternalStream.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/NonPositionableExternalStream.st	Thu Jan 05 21:02:10 2017 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
 	      All Rights Reserved
@@ -116,6 +118,62 @@
     ^ StdOutStream
 !
 
+makeBidirectionalPipe
+    "return an array with two streams - the first one for reading,
+     the second for writing.
+     This is the higher level equivalent of OperatingSystem>>makeBidirectionalPipe
+     (which returns an array of file-descriptors)."
+
+    |pipe rs ws|
+
+    pipe := OperatingSystem makeBidirectionalPipe.
+    pipe isNil ifTrue:[
+        "/ ok, maybe someone has forgotten to close a stream; enforce finalization and try again
+        'makePipe: enforcing finalization to close any open streams' infoPrintCR.
+        ObjectMemory garbageCollect; finalize.
+        pipe := OperatingSystem makeBidirectionalPipe.
+    ].
+
+    pipe isNil ifTrue:[
+        |errorNumber errorHolder|
+
+        errorNumber := OperatingSystem lastErrorNumber.
+        errorHolder := errorNumber.
+        OpenError newException
+            errorCode:errorNumber;
+            osErrorHolder:errorHolder;
+            raise.
+    ].
+
+    rs := self forFileDescriptor:(pipe at:1) mode:#readWrite buffered:false handleType:#pipeFilePointer.
+    ws := self forFileDescriptor:(pipe at:2) mode:#readWrite buffered:false handleType:#pipeFilePointer.
+    ^ Array with:rs with:ws
+
+    "
+     |pipe rs ws|
+
+     pipe := NonPositionableExternalStream makeBidirectionalPipe.
+     rs := pipe at:1.
+     ws := pipe at:2.
+
+     'read ...'.
+     [
+         1 to:10 do:[:i |
+             Transcript showCR:rs nextLine
+         ].
+         rs close.
+     ] forkAt:7.
+
+     'write ...'.
+     [
+         1 to:10 do:[:i |
+             ws nextPutAll:'hello world '; nextPutAll:i printString; cr
+         ].
+         ws close.
+     ] fork.
+    "
+!
+
 makePTYPair
     "return an array with two streams - the first one is the master,
      the second the slave of a ptym/ptys pair.
@@ -156,18 +214,26 @@
 
     pipe := OperatingSystem makePipe.
     pipe isNil ifTrue:[
-	"/ ok, maybe someone has forgotten to close a stream; enforce finalization and try again
-	'makePipe: enforcing finalization to close any open streams' infoPrintCR.
-	ObjectMemory garbageCollect; finalize.
-	pipe := OperatingSystem makePipe.
+        "/ ok, maybe someone has forgotten to close a stream; enforce finalization and try again
+        'makePipe: enforcing finalization to close any open streams' infoPrintCR.
+        ObjectMemory garbageCollect; finalize.
+        pipe := OperatingSystem makePipe.
     ].
 
-    pipe notNil ifTrue:[
-	rs := self forFileDescriptor:(pipe at:1) mode:#readonly buffered:false handleType:#pipeFilePointer.
-	ws := self forFileDescriptor:(pipe at:2) mode:#writeonly buffered:false handleType:#pipeFilePointer.
-	^ Array with:rs with:ws
+    pipe isNil ifTrue:[
+        |errorNumber errorHolder|
+
+        errorNumber := OperatingSystem lastErrorNumber.
+        errorHolder := errorNumber.
+        OpenError newException
+            errorCode:errorNumber;
+            osErrorHolder:errorHolder;
+            raise.
     ].
-    ^ nil
+
+    rs := self forFileDescriptor:(pipe at:1) mode:#readonly buffered:false handleType:#pipeFilePointer.
+    ws := self forFileDescriptor:(pipe at:2) mode:#writeonly buffered:false handleType:#pipeFilePointer.
+    ^ Array with:rs with:ws
 
     "
      |pipe rs ws|
@@ -178,18 +244,18 @@
 
      'read ...'.
      [
-	 1 to:10 do:[:i |
-	     Transcript showCR:rs nextLine
-	 ].
-	 rs close.
+         1 to:10 do:[:i |
+             Transcript showCR:rs nextLine
+         ].
+         rs close.
      ] forkAt:7.
 
      'write ...'.
      [
-	 1 to:10 do:[:i |
-	     ws nextPutAll:'hello world '; nextPutAll:i printString; cr
-	 ].
-	 ws close.
+         1 to:10 do:[:i |
+             ws nextPutAll:'hello world '; nextPutAll:i printString; cr
+         ].
+         ws close.
      ] fork.
     "
 
--- a/OSProcess.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/OSProcess.st	Thu Jan 05 21:02:10 2017 +0000
@@ -7,7 +7,7 @@
 Object subclass:#OSProcess
 	instanceVariableNames:'pid command environment directory inStream outStream errorStream
 		auxStream showWindow lineWise newPgrp exitStatus finishSema
-		shufflerProcesses streamsToClose'
+		shufflerProcesses streamsToClose terminateActionBlock'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'System-Support'
@@ -99,15 +99,14 @@
 
 !OSProcess methodsFor:'accessing'!
 
-accessor
-    ^ self
-!
-
 auxStream
     ^ auxStream
 !
 
 auxStream:something
+    "set an auxilliary input stream that will be available to the command as
+     file descriptor 3"
+
     auxStream := something.
 !
 
@@ -119,12 +118,14 @@
     "Created: / 10.11.1998 / 21:27:07 / cg"
 !
 
-command:something
-    "set the value of the instance variable 'command' (automatically generated)"
+command:aStringOrArray
+    "set the command to be executed.
+     If aStringOrArray is a String, the commandString is passed to a shell for execution
+     - see the description of 'sh -c' in your UNIX manual ('cmd.exe' in your Windows manual).
+     If aCommandString is an Array, the first element is the command to be executed,
+     and the other elements are the arguments to the command. No shell is invoked in this case."
 
-    command := something.
-
-    "Created: / 10.11.1998 / 21:27:07 / cg"
+    command := aStringOrArray.
 !
 
 directory
@@ -135,12 +136,10 @@
     "Created: / 10.11.1998 / 21:21:52 / cg"
 !
 
-directory:something
-    "set the value of the instance variable 'directory' (automatically generated)"
+directory:aString
+    "set the directory that will be set as the current directory of the command to be executed"
 
-    directory := something.
-
-    "Created: / 10.11.1998 / 21:21:52 / cg"
+    directory := aString.
 !
 
 environment
@@ -151,12 +150,10 @@
     "Created: / 10.11.1998 / 21:26:34 / cg"
 !
 
-environment:something
-    "set the value of the instance variable 'environment' (automatically generated)"
+environment:aDictionary
+    "set the environment variables of the command to be executed"
 
-    environment := something.
-
-    "Created: / 10.11.1998 / 21:27:07 / cg"
+    environment := aDictionary.
 !
 
 errorStream
@@ -167,20 +164,16 @@
     "Created: / 10.11.1998 / 21:26:34 / cg"
 !
 
-errorStream:something
-    "set the value of the instance variable 'errorStream' (automatically generated)"
+errorStream:aStream
+    "set the stream where the stderr output of the command is directed to"
 
-    errorStream := something.
-
-    "Created: / 10.11.1998 / 21:26:34 / cg"
+    errorStream := aStream.
 !
 
 exitStatus
-    "return the value of the instance variable 'exitStatus' (automatically generated)"
+    "answer the exit status of the command or nil, if the command has not yet been finished"
 
     ^ exitStatus
-
-    "Created: / 10.11.1998 / 21:24:55 / cg"
 !
 
 exitStatus:something
@@ -206,28 +199,33 @@
     "Created: / 10.11.1998 / 21:26:34 / cg"
 !
 
-inStream:something
-    "set the value of the instance variable 'inStream' (automatically generated)"
+inStream:aStream
+    "set the stream where the stdin input of the command is read from"
 
-    inStream := something.
-
-    "Created: / 10.11.1998 / 21:26:34 / cg"
+    inStream := aStream.
 !
 
 lineWise
     ^ lineWise
 !
 
-lineWise:something
-    lineWise := something.
+lineWise:aBoolean
+    "When setting to true, read linewise from the command's output and error.
+     This is a bit slower than lineWise = false.
+
+     You may use it also when streaming to e.g. Transcript"
+
+    lineWise := aBoolean.
 !
 
 newPgrp
     ^ newPgrp
 !
 
-newPgrp:something
-    newPgrp := something.
+newPgrp:aBoolean
+    "if aBoolean is true, a new process group will be created for the command and its subprocesses"
+
+    newPgrp := aBoolean.
 !
 
 outStream
@@ -238,15 +236,15 @@
     "Created: / 10.11.1998 / 21:26:34 / cg"
 !
 
-outStream:something
-    "set the value of the instance variable 'outStream' (automatically generated)"
+outStream:aStream
+    "set the stream where the stdout output of the command is directed to"
 
-    outStream := something.
-
-    "Created: / 10.11.1998 / 21:26:34 / cg"
+    outStream := aStream.
 !
 
 pid
+    "answer the pid of the process the command is running in or nil, if the command has not yet been started."
+
     ^ pid
 !
 
@@ -258,8 +256,30 @@
     ^ showWindow
 !
 
-showWindow:something
-    showWindow := something.
+showWindow:aBooleanOrNil
+    "This parameter is ignored on Unix systems.
+
+     You can control (have to - sigh) if a window should be shown for the command or not.
+     This is the OS's H_SHOWWINDOW argument.
+     If you pass nil as showWindow-argument, the OS's default is used for the particular
+     command, which is correct most of the time: i.e. a notepad will open its window, other (non-UI)
+     executables will not.
+     However, some command-line executables show a window, even if they should not.
+     (and also, there seems to be an inconsistency between windows7 and newer windows: in newer,
+     a shell command opens a cmd-window, whereas in windows7 it did not)
+     In this case, pass an explicit false argument to suppress it."
+
+    showWindow := aBooleanOrNil.
+!
+
+terminateActionBlock
+    ^ terminateActionBlock
+!
+
+terminateActionBlock:aBlock
+    "set the block that will be executed when the command has been finished or terminated."
+
+    terminateActionBlock := aBlock.
 ! !
 
 !OSProcess methodsFor:'initialization'!
@@ -391,10 +411,14 @@
 
 !OSProcess methodsFor:'queries'!
 
+finishedWithSuccess
+    ^ exitStatus notNil and:[exitStatus success].
+!
+
 isAlive
     "answer true, if the process is still alive"
 
-    ^ pid notNil and:[exitStatus notNil]
+    ^ pid notNil and:[exitStatus isNil]
 !
 
 isDead
@@ -417,7 +441,8 @@
     [
         ok := self startProcess.
         ok ifTrue:[
-            ok := self waitUntilFinished.
+            self waitUntilFinished.
+            ok := self finishedWithSuccess.
         ].
     ] ifCurtailed:[
         "/ we were interrupted -
@@ -436,10 +461,10 @@
      Answer true if the command could be started, false if not.
      Return immediately (do not wait until the command is finished)." 
 
-    |nullStream externalInStream externalAuxStream externalErrorStream externalOutStream|
+    |externalInStream externalAuxStream externalErrorStream externalOutStream|
 
-    shufflerProcesses := OrderedCollection new.
-    streamsToClose := OrderedCollection new:3.
+    shufflerProcesses := OrderedCollection new:4.
+    streamsToClose := OrderedCollection new:2.
 
     externalInStream := self setupShufflerForInput:inStream.
     externalAuxStream := self setupShufflerForInput:auxStream.
@@ -450,41 +475,21 @@
         externalOutStream := self setupShufflerForOutput:outStream.
     ].
 
-    "make sure, that the command gets a stdin, stdout and stderr"
-    externalInStream isNil ifTrue:[
-        externalInStream := nullStream := Filename nullDevice readWriteStream.
-        streamsToClose add:nullStream.
-    ].
-    externalOutStream isNil ifTrue:[
-        nullStream isNil ifTrue:[
-            nullStream := Filename nullDevice writeStream.
-            streamsToClose add:nullStream.
-        ].
-        externalOutStream := nullStream.
-    ].
-    externalErrorStream isNil ifTrue:[
-        nullStream isNil ifTrue:[
-            nullStream := Filename nullDevice writeStream.
-            streamsToClose add:nullStream.
-        ].
-        externalErrorStream := nullStream.
-    ].
-
     "start the command"
-    finishSema := Semaphore new.
+    finishSema := EventSemaphore new.
 
     Processor 
         monitor:[
             pid := OperatingSystem
-                    startProcess:command
-                    inputFrom:externalInStream
-                    outputTo:externalOutStream
-                    errorTo:externalErrorStream
-                    auxFrom:externalAuxStream
-                    environment:environment
-                    inDirectory:directory
-                    newPgrp:newPgrp
-                    showWindow:showWindow.
+                        startProcess:command
+                        inputFrom:externalInStream
+                        outputTo:externalOutStream
+                        errorTo:externalErrorStream
+                        auxFrom:externalAuxStream
+                        environment:environment
+                        inDirectory:directory
+                        newPgrp:newPgrp
+                        showWindow:showWindow.
         ] 
         action:[:status |
             status stillAlive ifFalse:[
@@ -497,6 +502,7 @@
                      They close the local side of the pipe when being terminated"
                     eachProcess terminate.
                 ].
+                terminateActionBlock value.
                 finishSema signal.
             ].
         ].
@@ -512,6 +518,7 @@
         ].
         shufflerProcesses := nil.
         exitStatus := OperatingSystem osProcessStatusClass processCreationFailure.
+        finishSema signal.
         ^ false.
     ].
 
@@ -523,21 +530,27 @@
 kill
     "kill the process - the process does not get the chance to clean up"
     
-    OperatingSystem killProcess:pid.
+    pid notNil ifTrue:[
+        OperatingSystem killProcess:pid.
+    ].
 !
 
 killGroup
     "kill the processGroup - the processes do not get the chance to clean up"
 
-    OperatingSystem 
-        killProcessGroup:pid;
-        killProcess:pid.
+    pid notNil ifTrue:[
+        OperatingSystem 
+            killProcessGroup:pid;
+            killProcess:pid.
+    ].
 !
 
 terminate
     "terminate the process gracefully"
 
-    OperatingSystem terminateProcess:pid.
+    pid notNil ifTrue:[
+        OperatingSystem terminateProcess:pid.
+    ].
 !
 
 terminateGroup
@@ -545,28 +558,35 @@
      Under Windows, these is the same as terminateWithhAllChildren,
      under unix, this terminates a subset of all children"
 
-    OperatingSystem 
-        terminateProcessGroup:pid;
-        terminateProcess:pid.
+    pid notNil ifTrue:[
+        OperatingSystem 
+            terminateProcessGroup:pid;
+            terminateProcess:pid.
+    ].
 ! !
 
 !OSProcess methodsFor:'waiting'!
 
 waitUntilFinished
+    ^ self waitUntilFinishedWithTimeout:nil
+!
+
+waitUntilFinishedWithTimeout:timeout
     |processList|
 
-    finishSema waitUncounted.
+    (finishSema waitWithTimeout:timeout) isNil ifTrue:[
+        "timed out"
+        ^ nil.
+    ].
 
     "have to wait until the shufflers have finished their work"
-    shufflerProcesses notEmptyOrNil ifTrue:[
-        processList := shufflerProcesses.
+    processList := shufflerProcesses.
+    processList notEmptyOrNil ifTrue:[
         processList do:[:eachProcess | 
             eachProcess waitUntilTerminated.
         ].
         shufflerProcesses := nil.
     ].
-
-    ^ exitStatus notNil and:[exitStatus success].
 ! !
 
 !OSProcess class methodsFor:'documentation'!
--- a/Object.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Object.st	Thu Jan 05 21:02:10 2017 +0000
@@ -257,6 +257,7 @@
     "Modified: / 4.8.1999 / 08:54:06 / stefan"
 ! !
 
+
 !Object class methodsFor:'Compatibility-ST80'!
 
 rootError
@@ -495,6 +496,7 @@
     InfoPrinting := aBoolean
 ! !
 
+
 !Object class methodsFor:'queries'!
 
 isAbstract
@@ -517,6 +519,10 @@
 ! !
 
 
+
+
+
+
 !Object methodsFor:'Compatibility-Dolphin'!
 
 stbFixup: anSTBInFiler at: newObjectIndex
@@ -688,6 +694,8 @@
     "
 ! !
 
+
+
 !Object methodsFor:'accessing'!
 
 _at:index
@@ -1784,6 +1792,8 @@
     "
 ! !
 
+
+
 !Object methodsFor:'attributes access'!
 
 objectAttributeAt:attributeKey
@@ -1911,6 +1921,8 @@
 ! !
 
 
+
+
 !Object methodsFor:'change & update'!
 
 broadcast:aSelectorSymbol
@@ -2091,6 +2103,7 @@
     ^ aBlock ensure:[ self addDependent:someone ]
 ! !
 
+
 !Object methodsFor:'comparing'!
 
 = anObject
@@ -2380,6 +2393,13 @@
     ^ Array with:self
 !
 
+asCollectionDo:aBlock
+    "enumerate myself as a Collection.
+     Redefined in collection."
+
+    ^ aBlock value:self
+!
+
 asLink
     "return a valueLink for the receiver.
      Used to make sure the receiver can be added to a linked list"
@@ -8180,6 +8200,7 @@
     ^ self
 ! !
 
+
 !Object methodsFor:'secure message sending'!
 
 ?:selector
@@ -8785,6 +8806,7 @@
     "
 ! !
 
+
 !Object methodsFor:'synchronized evaluation'!
 
 freeSynchronizationSemaphore
@@ -10579,6 +10601,9 @@
     ^ aVisitor visitObject:self with:aParameter
 ! !
 
+
+
+
 !Object class methodsFor:'documentation'!
 
 version
--- a/OrderedDictionary.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/OrderedDictionary.st	Thu Jan 05 21:02:10 2017 +0000
@@ -144,12 +144,8 @@
 
 !OrderedDictionary class methodsFor:'instance creation'!
 
-new
-        ^ super new initializeOrder
-!
-
-new: anInteger
-        ^(super new: anInteger) initializeOrder
+new:anInteger
+    ^ (super new:anInteger) initializeOrder:anInteger
 ! !
 
 !OrderedDictionary methodsFor:'accessing'!
@@ -847,8 +843,8 @@
 
 !OrderedDictionary methodsFor:'initialization'!
 
-initializeOrder
-        order := OrderedCollection new
+initializeOrder:count
+    order := OrderedCollection new:count
 ! !
 
 !OrderedDictionary methodsFor:'private'!
--- a/OrderedSet.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/OrderedSet.st	Thu Jan 05 21:02:10 2017 +0000
@@ -108,16 +108,8 @@
 
 !OrderedSet class methodsFor:'instance creation'!
 
-new
-        ^super new initializeOrder
-
-    "Created: / 16.11.2001 / 10:10:37 / cg"
-!
-
-new: anInteger
-        ^(super new: anInteger) initializeOrder
-
-    "Created: / 16.11.2001 / 10:10:07 / cg"
+new:anInteger
+    ^ (super new:anInteger) initializeOrder:anInteger
 ! !
 
 !OrderedSet methodsFor:'accessing'!
@@ -259,7 +251,7 @@
     "remove all elements from the receiver. Returns the receiver."
 
     super removeAll.
-    self initializeOrder.
+    self initializeOrder:0.
 
     "Created: / 16.11.2001 / 10:21:40 / cg"
 !
@@ -413,10 +405,8 @@
 
 !OrderedSet methodsFor:'initialization'!
 
-initializeOrder
-    order := OrderedCollection new
-
-    "Created: / 16.11.2001 / 10:06:05 / cg"
+initializeOrder:count
+    order := OrderedCollection new:count
 ! !
 
 !OrderedSet methodsFor:'searching'!
--- a/PipeStream.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/PipeStream.st	Thu Jan 05 21:02:10 2017 +0000
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
 	      All Rights Reserved
@@ -14,7 +16,7 @@
 "{ NameSpace: Smalltalk }"
 
 NonPositionableExternalStream subclass:#PipeStream
-	instanceVariableNames:'commandString pid exitStatus exitSema exitAction'
+	instanceVariableNames:'commandString osProcess'
 	classVariableNames:'BrokenPipeSignal'
 	poolDictionaries:''
 	category:'Streams-External'
@@ -222,7 +224,7 @@
 	|p|
 
 	p := PipeStream bidirectionalFor:'cat -u'.
-	p nextPutAll:'Wer ist der Bürgermeister von Wesel'; cr.
+	p nextPutAll:'Wer ist der Bürgermeister von Wesel'; cr.
 	Transcript showCR:p nextLine.
 	p close
     "
@@ -275,48 +277,53 @@
      The commands error output is send to my own error output."
 
     ^ self
-	readingFrom:commandString
-	errorDisposition:#stderr
-	inDirectory:nil
+        readingFrom:commandString
+        errorDisposition:#stderr
+        inDirectory:nil
 
     "unix:
-	PipeStream readingFrom:'ls -l'.
-    "
-
-    "
-	|p|
-
-	p := PipeStream readingFrom:'ls -l'.
-	Transcript showCR:p nextLine.
-	p close
+        PipeStream readingFrom:'ls -l'.
     "
 
     "
-	|s|
-	s := PipeStream readingFrom:'sh -c sleep\ 600'.
-	(Delay forSeconds:2) wait.
-	s shutDown
+        |p|
+
+        p := PipeStream readingFrom:'ls -l'.
+        Transcript showCR:p nextLine.
+        p close
     "
 
-    "vms:
-	PipeStream readingFrom:'dir'.
+
+    "
+        |p|
+
+        p := PipeStream readingFrom:'echo error >&2'.
+        Transcript showCR:p nextLine.
+        p close
     "
 
     "
-	|p|
-	p := PipeStream readingFrom:'dir'.
-	Transcript showCR:p nextLine.
-	p close
+        |s|
+        s := PipeStream readingFrom:'sh -c sleep\ 600'.
+        (Delay forSeconds:2) wait.
+        s abortAndClose
     "
 
-    "msdos:
-	PipeStream readingFrom:'dir'.
+    "
+        |p|
+        p := PipeStream readingFrom:'dir'.
+        Transcript showCR:p nextLine.
+        p close
+    "
+
+    "Windows:
+        PipeStream readingFrom:'dir'.
     "
     "
-	|p|
-	p := PipeStream readingFrom:'dir'.
-	Transcript showCR:p nextLine.
-	p close
+        |p|
+        p := PipeStream readingFrom:'dir'.
+        Transcript showCR:p nextLine.
+        p close
     "
 
     "Modified: 24.4.1996 / 09:09:25 / stefan"
@@ -334,10 +341,27 @@
      Nil is treated like #stderr"
 
     ^ self basicNew
-	openPipeFor:commandString
-	withMode:#r
-	errorDisposition:errorDisposition
-	inDirectory:aDirectory
+        openPipeFor:commandString
+        withMode:#r
+        errorDisposition:errorDisposition
+        inDirectory:aDirectory
+
+
+    "
+        |p|
+
+        p := PipeStream readingFrom:'bla' errorDisposition:Transcript inDirectory:nil.
+        Transcript showCR:p nextLine.
+        p close
+    "
+
+    "
+        |p|
+
+        p := PipeStream readingFrom:'bla' errorDisposition:#inline inDirectory:nil.
+        Transcript showCR:p nextLine.
+        p close
+    "
 !
 
 readingFrom:commandString inDirectory:aDirectory
@@ -472,15 +496,21 @@
 exitStatus
     "return the exitStatus"
 
-    ^ exitStatus
-
+    osProcess isNil ifTrue:[
+        ^ nil.
+    ].
+    ^ osProcess exitStatus.
+    
     "Created: 28.12.1995 / 14:54:41 / stefan"
 !
 
 pid
     "return pid"
 
-    ^ pid
+    osProcess isNil ifTrue:[
+        ^ nil.
+    ].
+    ^ osProcess pid.
 
     "Created: 28.12.1995 / 14:54:30 / stefan"
 ! !
@@ -511,10 +541,8 @@
 
     handle notNil ifTrue:[
         super close.
-        pid notNil ifTrue:[
-            "/ wait for the pipe-command to terminate.
-            self waitForPipeCommandWithTimeout:nil.
-        ].
+        "/ wait for the pipe-command to terminate.
+        self waitForPipeCommandWithTimeout:nil.
     ].
 
     "Modified: / 12.9.1998 / 16:51:04 / cg"
@@ -568,37 +596,24 @@
     int retVal;
 
     if ((fp = __INST(handle)) != nil) {
-	__INST(handle) = nil;
-	f = __FILEVal(fp);
-	if (@global(FileOpenTrace) == true) {
-	    console_fprintf(stderr, "close [PipeStream] %"_lx_" fd=%d\n", (INT)f, fileno(f));
-	}
+        __INST(handle) = nil;
+        f = __FILEVal(fp);
+        if (@global(FileOpenTrace) == true) {
+            console_fprintf(stderr, "close [PipeStream] %"_lx_" fd=%d\n", (INT)f, fileno(f));
+        }
 #ifdef __win32__
-	do {
-	    __threadErrno = 0;
-	    retVal = __STX_C_NOINT_CALL1( "close", (void*)close, (void*)fileno(f) );
-	} while ((retVal < 0) && (__threadErrno == EINTR));
+        do {
+            __threadErrno = 0;
+            retVal = __STX_C_NOINT_CALL1( "close", (void*)close, (void*)fileno(f) );
+        } while ((retVal < 0) && (__threadErrno == EINTR));
 #else
-	__BEGIN_INTERRUPTABLE__
-	close(fileno(f));
-	__END_INTERRUPTABLE__
+        __BEGIN_INTERRUPTABLE__
+        close(fileno(f));
+        __END_INTERRUPTABLE__
 #endif
     }
 #endif /* not transputer  */
 %}.
-    exitAction notNil ifTrue:[
-	action := exitAction.
-	exitAction := nil.
-	action value.
-    ]
-!
-
-exitAction:aBlock
-    "define a block to be evaluated when the pipe is closed.
-     This is only used with VMS, to remove any temporary COM file.
-     (see readingFrom:inDirectory:)"
-
-    exitAction := aBlock
 !
 
 openPipeFor:aCommandString withMode:rwMode errorDisposition:errorDisposition inDirectory:aDirectory
@@ -611,9 +626,7 @@
      #stderr causes it to be written to smalltalks own stderr.
      Nil is treated like #stderr"
 
-    |blocked pipeFdArray execFdArray execFd myFd shellAndArgs
-     shellPath shellArgs mbx mbxName
-     realCmd execDirectory tmpComFile nullOutput resultPid errorNumber|
+    |pipeArray remotePipeEnd nullOutput errorNumber myPipeEnd result|
 
     handle notNil ifTrue:[
         "the pipe was already open ...
@@ -632,185 +645,95 @@
     ]].
 
     lastErrorNumber := nil.
-    exitStatus := nil.
-    exitSema := Semaphore new name:'pipe exitSema'.
-
-    realCmd := aCommandString.
-    execDirectory := aDirectory.
-    execFdArray := #(0 1 2) copy.
+    commandString := aCommandString.
+    "stdio lib does not work with blocking pipes and interrupts
+     for WIN, Linux, Solaris and probably any other UNIX"
+    buffered := false.
+    hitEOF := false.
+    binary := false.
 
-    OperatingSystem isVMSlike ifTrue:[
-        "/
-        "/ the generated COM-file includes a 'set default'
-        "/
-        tmpComFile := OperatingSystem createCOMFileForVMSCommand:aCommandString in:aDirectory.
-        realCmd := '@' , tmpComFile osName.
-        execDirectory := nil.
+    osProcess := OSProcess new 
+                    command:aCommandString;
+                    directory:aDirectory.
 
-        mbx := OperatingSystem createMailBox.
-        mbx isNil ifTrue:[
+    mode == #readwrite ifTrue:[
+        pipeArray := self class makeBidirectionalPipe.
+        pipeArray isNil ifTrue:[
             lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
-            tmpComFile delete.
             ^ self openError:errorNumber.
         ].
-        mbxName := OperatingSystem mailBoxNameOf:mbx.
-
-        "/ 'mailBox is ' print. mbx print. ' name is ' print. mbxName printCR.
-        shellPath := ''.
-        shellArgs := realCmd.
-
-        rwMode = #r ifTrue:[
-            "redirect stdout of subprocess to write to mailbox"
-            execFdArray at:2 put:mbx.
-        ] ifFalse:[
-            "redirect stdin of subprocess to read from mailbox"
-            execFdArray at:1 put:mbx.
+        myPipeEnd := pipeArray at:1.
+        remotePipeEnd := pipeArray at:2.
+        osProcess inStream:remotePipeEnd.
+        osProcess outStream:remotePipeEnd.
+    ] ifFalse:[
+        pipeArray := self class makePipe.
+        pipeArray isNil ifTrue:[
+            lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
+            ^ self openError:errorNumber.
         ].
-    ] ifFalse:[
-        shellAndArgs := OperatingSystem commandAndArgsForOSCommand:realCmd.
-        shellPath := shellAndArgs at:1.
-        shellArgs := shellAndArgs at:2.
 
-        mode == #readwrite ifTrue:[
-            pipeFdArray := OperatingSystem makeBidirectionalPipe.
-            pipeFdArray isNil ifTrue:[
-                lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
-                ^ self openError:errorNumber.
-            ].
-            myFd := pipeFdArray at:1.
-            execFd := pipeFdArray at:2.
-            execFdArray at:1 put:execFd.
-            execFdArray at:2 put:execFd.
+        mode == #readonly ifTrue:[
+            "redirect stdout of subprocess to write to pipe"
+            myPipeEnd := pipeArray at:1.
+            remotePipeEnd := pipeArray at:2.
+            osProcess outStream:remotePipeEnd.
         ] ifFalse:[
-            pipeFdArray := OperatingSystem makePipe.
-            pipeFdArray isNil ifTrue:[
-                lastErrorNumber := errorNumber := OperatingSystem currentErrorNumber.
-                ^ self openError:errorNumber.
-            ].
-
-            mode == #readonly ifTrue:[
-                "redirect stdout of subprocess to write to pipe"
-                myFd := pipeFdArray at:1.
-                execFd := pipeFdArray at:2.
-                execFdArray at:2 put:execFd.
-            ] ifFalse:[
-                "redirect stdin of subprocess to read from pipe"
-                myFd := pipeFdArray at:2.
-                execFd := pipeFdArray at:1.
-                execFdArray at:1 put:execFd.
-            ].
+            "redirect stdin of subprocess to read from pipe"
+            myPipeEnd := pipeArray at:2.
+            remotePipeEnd := pipeArray at:1.
+            osProcess inStream:remotePipeEnd.
         ].
     ].
 
     errorDisposition == #discard ifTrue:[
         nullOutput := Filename nullDevice writeStream.
-        execFdArray at:3 put:nullOutput fileDescriptor
-    ] ifFalse:[
-        (errorDisposition == #inline or:[errorDisposition == #stdout]) ifTrue:[
-            execFdArray at:3 put:1
-        ] ifFalse:[
-"/            errorDisposition isStream ifTrue:[
-"/self halt.
-"/            ].
-        ].
-    ].
-
-    "/ must block here, to avoid races due to early finishing
-    "/ subprocesses ...
-
-    blocked := OperatingSystem blockInterrupts.
+        osProcess errorStream:nullOutput.
+    ] ifFalse:[(errorDisposition == #inline or:[errorDisposition == #stdout]) ifTrue:[
+        osProcess errorStream:osProcess outStream.
+    ] ifFalse:[(errorDisposition == #stderr or:[errorDisposition isNil]) ifTrue:[
+        osProcess errorStream:Stderr.
+    ] ifFalse:[errorDisposition isStream ifTrue:[
+        osProcess errorStream:errorDisposition.
+    ]]]].
 
-    "beware: pid may change if subprocess is fast"
-    pid := resultPid :=  Processor
-               monitor:[
-                  OperatingSystem
-                      exec:shellPath
-                      withArguments:shellArgs
-                      environment:nil
-                      fileDescriptors:execFdArray
-                      fork:true
-                      newPgrp:true
-                      inDirectory:execDirectory
-                      showWindow:false.
-               ]
-               action:[:status |
-                  status stillAlive ifFalse:[
-                      exitStatus := status.
+    osProcess terminateActionBlock:[
+            "writing doesn't make sense - there is no reader any longer"
+            mode == #readwrite ifTrue:[
+                "... but allow to read the rest of the command's output"
+                self shutDownOutput.
+            ] ifFalse:[mode == #writeonly ifTrue:[
+                self closeFileDescriptor.
+            ]].
+       ].
 
-                      "writing doesn't make sense - there is no reader any longer"
-                      mode == #readwrite ifTrue:[
-                          "... but allow to read the rest of the command's output"
-                          self shutDownOutput.
-                      ] ifFalse:[mode == #writeonly ifTrue:[
-                          self closeFileDescriptor.
-                      ]].
-
-                      OperatingSystem closePid:pid.
-                      pid := nil.
-                      exitSema signal.
-                  ].
-               ].
+    result := osProcess startProcess.
 
     "subprocess has been created.
      close unused filedescriptors"
-
-    execFd notNil ifTrue:[
-        OperatingSystem closeFd:execFd.
+    remotePipeEnd notNil ifTrue:[
+        remotePipeEnd close.
     ].
-
     nullOutput notNil ifTrue:[
         nullOutput close
     ].
 
-    resultPid notNil ifTrue:[
+    result ifTrue:[
         "successfull creation of subprocesss"
-        OperatingSystem isVMSlike ifTrue:[
-            "/
-            "/ reopen the mailbox as a file ...
-            "/
-            mbxName := OperatingSystem mailBoxNameOf:mbx.
-            mbxName notNil ifTrue:[
-                super open:mbxName withMode:rwMode.
-                exitAction := [tmpComFile delete].
-            ].
-        ] ifFalse:[
-            self setFileHandle:myFd mode:rwMode.
-            handleType := #pipeFilePointer.
-        ]
+        self setFileHandle:myPipeEnd fileHandle mode:rwMode.
+        myPipeEnd unregisterForFinalization.    "make sure filedesciptor is not closed by finalizer"
+        myPipeEnd := nil.
+        handleType := #pipeFilePointer.
     ] ifFalse:[
-        "creation of subprocesss failed"
-        lastErrorNumber := OperatingSystem currentErrorNumber.
-        OperatingSystem isVMSlike ifTrue:[
-            OperatingSystem destroyMailBox:mbx.
-            tmpComFile delete.
-        ] ifFalse:[
-            OperatingSystem closeFd:myFd.
-        ].
-    ].
-
-    blocked ifFalse:[
-        OperatingSystem unblockInterrupts
-    ].
-
-    (resultPid isNil or:[lastErrorNumber notNil]) ifTrue:[
-        "
-         the pipe open failed for some reason ...
+        "the pipe open failed for some reason ...
          ... this may be either due to an invalid command string,
          or due to the system running out of memory (when forking
-         the unix process)
-        "
-        exitAction value.
+         the unix process)"
+        lastErrorNumber := OperatingSystem lastErrorNumber.
+        myPipeEnd close.
         ^ self openError:lastErrorNumber.
     ].
 
-    commandString := realCmd.
-
-    "stdio lib does not work with blocking pipes and interrupts
-     for WIN, Linux, Solaris and probably any other UNIX"
-    buffered := false.
-    position := 0.
-    hitEOF := false.
-    binary := false.
     self registerForFinalization.
 
     "Modified: / 23.4.1996 / 17:05:59 / stefan"
@@ -819,11 +742,8 @@
 !
 
 terminatePipeCommand
-    |tpid|
-
-    (tpid := pid) notNil ifTrue:[
-	OperatingSystem terminateProcessGroup:tpid.
-	OperatingSystem terminateProcess:tpid.
+    osProcess notNil ifTrue:[
+        osProcess terminateGroup.
     ].
 !
 
@@ -831,14 +751,10 @@
     "wait for the pipe command to terminate itself.
      Return true, if a timeout occurred."
 
-    pid notNil ifTrue:[
-	[
-	    pid notNil ifTrue:[
-		exitSema waitWithTimeout:seconds.
-	    ]
-	] valueUninterruptably
+    osProcess notNil ifTrue:[
+        ^ osProcess finishSema waitWithTimeout:seconds.
     ].
-    ^ pid notNil
+    ^ false
 ! !
 
 !PipeStream class methodsFor:'documentation'!
--- a/RecursionLock.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/RecursionLock.st	Thu Jan 05 21:02:10 2017 +0000
@@ -183,7 +183,6 @@
     |wasBlocked|
 
     process ~~ Processor activeProcess ifTrue:[
-        "I have already got the lock"
         self error:'RecursionLock - signaling process doesn''t own the lock'.
     ].
 
--- a/Semaphore.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Semaphore.st	Thu Jan 05 21:02:10 2017 +0000
@@ -410,17 +410,17 @@
 
      NOTE: must be called with blocked interrupts"
 
-    "for now"
     waitingProcesses isNil ifTrue:[
-	waitingProcesses := Array with:aProcess
+        "for now - assume that there is probably only one waiter"
+        waitingProcesses := Array with:aProcess
     ] ifFalse:[
-	waitingProcesses isArray ifTrue:[
-	    "add 2 to reserve space for additional waiters"
-	    waitingProcesses := (OrderedCollection new:waitingProcesses size + 2)
-				    addAll:waitingProcesses;
-				    yourself.
-	].
-	waitingProcesses add:aProcess.
+        waitingProcesses isArray ifTrue:[
+            "add 2 to reserve space for additional waiters"
+            waitingProcesses := (OrderedCollection new:waitingProcesses size + 2)
+                                    addAll:waitingProcesses;
+                                    yourself.
+        ].
+        waitingProcesses add:aProcess.
     ].
 
 "/    "Sort, so that higher priority process are resumed first.
--- a/Smalltalk.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Smalltalk.st	Thu Jan 05 21:02:10 2017 +0000
@@ -2754,7 +2754,11 @@
             AbstractSourceCodeManager notNil ifTrue:[
                 sourceCodeManager := AbstractSourceCodeManager sourceCodeManagerForPackage:packageString.
                 sourceCodeManager notNil ifTrue:[
-                    ^ sourceCodeManager loadPackageWithId:packageString fromRepositoryAsAutoloaded:doLoadAsAutoloaded
+                    PackageLoadError handle:[:ex2 |
+                        ex reject
+                    ] do:[    
+                        ^ sourceCodeManager loadPackageWithId:packageString fromRepositoryAsAutoloaded:doLoadAsAutoloaded
+                    ].
                 ].
             ].
         ].
--- a/SomeNumber.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/SomeNumber.st	Thu Jan 05 21:02:10 2017 +0000
@@ -11,6 +11,8 @@
 "
 "{ Package: 'stx:libbasic' }"
 
+"{ NameSpace: Smalltalk }"
+
 MetaNumber subclass:#SomeNumber
 	instanceVariableNames:'realNumber'
 	classVariableNames:''
@@ -86,6 +88,15 @@
      as the receiver, false otherwise."
 
     ^ something equalFromSomeNumber:self
+
+    "
+        Float infinity = Infinity positive
+        Infinity positive = Float infinity 
+        Float negativeInfinity = Infinity negative
+        Infinity negative = Float negativeInfinity 
+        Float negativeInfinity = Infinity positive
+        Infinity positive = Float negativeInfinity 
+    "
 ! !
 
 !SomeNumber methodsFor:'printing'!
@@ -106,6 +117,10 @@
 
 !SomeNumber methodsFor:'queries'!
 
+isInfinite
+    ^ realNumber isInfinite
+!
+
 sign
     "return the sign of the receiver (-1, 0 or 1)"
 
@@ -115,6 +130,6 @@
 !SomeNumber class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/SomeNumber.st,v 1.4 2014-06-30 14:27:34 stefan Exp $'
+    ^ '$Header$'
 ! !
 
--- a/UnixOperatingSystem.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/UnixOperatingSystem.st	Thu Jan 05 21:02:10 2017 +0000
@@ -3184,42 +3184,6 @@
 !UnixOperatingSystem class methodsFor:'executing OS commands-implementation'!
 
 exec:aCommandPathArg withArguments:argColl environment:environmentDictionary
-    fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory
-
-    ^ self
-        exec:aCommandPathArg withArguments:argColl environment:environmentDictionary
-        fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory showWindow:nil
-
-    "
-     |id|
-
-     id := OperatingSystem fork.
-     id == 0 ifTrue:[
-        'I am the child'.
-        OperatingSystem exec:'/bin/ls' withArguments:#('ls' '/tmp').
-        'not reached'.
-     ]
-    "
-    "
-     |id|
-
-     id := OperatingSystem fork.
-     id == 0 ifTrue:[
-        'I am the child'.
-        OperatingSystem
-           exec:'/bin/sh'
-           withArguments:#('sh' '-c' 'sleep 2;echo 1;sleep 2;echo 2').
-        'not reached'.
-     ].
-     id printNL.
-     (Delay forSeconds:3.5) wait.
-     'killing ...' printNL.
-     OperatingSystem sendSignal:(OperatingSystem sigTERM) to:id.
-     OperatingSystem sendSignal:(OperatingSystem sigKILL) to:id
-    "
-!
-
-exec:aCommandPathArg withArguments:argColl environment:environmentDictionary
     fileDescriptors:fdColl fork:doFork newPgrp:newPgrp inDirectory:aDirectory showWindow:ignoredHere
 
     "Internal lowLevel entry for combined fork & exec;
@@ -3575,245 +3539,28 @@
      ].
      'Parent t=' print. (Timestamp now - t1) printCR. 
     "
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-    errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
-    environment:anEvironmentDictionary inDirectory:dir
-
-    ^ self
-        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-        errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
-        environment:anEvironmentDictionary inDirectory:dir showWindow:nil
-
-    "blocking at current prio (i.e. only higher prio threads execute):
-
-     OperatingSystem executeCommand:'ls -l > out'.
-     OperatingSystem executeCommand:#('/bin/ls' '-l') outputTo:Transcript.
-    "
-
-    "non-blocking (lower prio threads continue):
-
-     |in out err pid sema|
-
-     in := 'out' asFilename readStream.
-     out := 'out2' asFilename writeStream.
-     err := 'err' asFilename writeStream.
-
-     sema := Semaphore new.
-     pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
-
-     The following will no longer work. monitorPid has disappeared
-
-     pid notNil ifTrue:[
-         Processor monitorPid:pid action:[:osStatus | sema signal ].
-     ].
-     in close.
-     out close.
-     err close.
-     sema wait.
-     Transcript showCR:'finished'
-    "
-
-    "
-     |pid sema|
-
-     sema := Semaphore new.
-
-     Processor
-            monitor:[
-                pid := OperatingSystem startProcess:'(sleep 2; ls -l) > out 2>err'
-            ]
-            action:[:osStatus | sema signal ].
-
-     sema wait.
-     Transcript showCR:'finished'
-    "
-
-    "
-     |pid sema|
-
-     sema := Semaphore new.
-
-     Processor
-            monitor:[
-                pid := OperatingSystem startProcess:'(sleep 1; echo 1; sleep 9; ls -l) > out 2>err'
-            ]
-            action:[:osStatus | sema signal ].
-
-     Delay waitForSeconds:2.
-     OperatingSystem terminateProcess:pid.
-     Transcript showCR:'terminated'
-    "
-
-    "Modified: / 21.3.1997 / 10:04:35 / dq"
-    "Modified: / 15.7.1997 / 16:03:51 / stefan"
-    "Modified: / 5.6.1998 / 19:03:51 / cg"
-    "Created: / 12.11.1998 / 14:39:20 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-    errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
-    environment:anEvironmentDictionary inDirectory:dir newPgrp:newPgrp showWindow:ignoredHere
-
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     If aCommandString is a String, the commandString is passed to a shell for execution
-     - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
-     If aCommandString is an Array, the first element is the command to be executed,
-     and the other elements are the arguments to the command. No shell is invoked in this case.
-     The command gets stdIn, stdOut and stdErr assigned from the arguments;
-     each may be nil.
-     Return the processId if successful, nil otherwise.
-     Use #monitorPid:action: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-    |nullStream in out err shellAndArgs rslt auxFd|
-
-    aCommandString isNil ifTrue:[^ nil].
-
-    (in := anExternalInStream) isNil ifTrue:[
-        nullStream := Filename nullDevice readWriteStream.
-        in := nullStream.
-    ].
-    (out := anExternalOutStream) isNil ifTrue:[
-        nullStream isNil ifTrue:[nullStream := Filename nullDevice writeStream].
-        out := nullStream.
-    ].
-    (err := anExternalErrStream) isNil ifTrue:[
-        err := out
-    ].
-    anAuxiliaryStream notNil ifTrue:[
-        auxFd := anAuxiliaryStream fileDescriptor
-    ].
-
-    shellAndArgs := self commandAndArgsForOSCommand:aCommandString.
-
-    rslt := self
-        exec:(shellAndArgs at:1)
-        withArguments:(shellAndArgs at:2)
-        environment:anEvironmentDictionary
-        fileDescriptors:(Array with:in fileDescriptor
-                               with:out fileDescriptor
-                               with:err fileDescriptor
-                               with:auxFd)
-        fork:true
-        newPgrp:newPgrp
-        inDirectory:dir.
-
-    nullStream notNil ifTrue:[
-        nullStream close.
-    ].
-
-    ^ rslt
-
-    "blocking at current prio (i.e. only higher prio threads execute):
-
-     OperatingSystem executeCommand:'ls -l > out'.
-     OperatingSystem executeCommand:#('/bin/ls' '-l') outputTo:Transcript.
-    "
-
-    "non-blocking (lower prio threads continue):
-
-     |in out err pid sema|
-
-     in := 'out' asFilename readStream.
-     out := 'out2' asFilename writeStream.
-     err := 'err' asFilename writeStream.
-
-     sema := Semaphore new.
-     pid := OperatingSystem startProcess:'sleep 10; grep drw' inputFrom:in outputTo:out errorTo:err.
-
-     The following will no longer work. monitorPid has disappeared
-
-     pid notNil ifTrue:[
-         Processor monitorPid:pid action:[:osStatus | sema signal ].
-     ].
-     in close.
-     out close.
-     err close.
-     sema wait.
-     Transcript showCR:'finished'
-    "
-
-    "
-     |pid sema|
-
-     sema := Semaphore new.
-
-     Processor
-            monitor:[
-                pid := OperatingSystem startProcess:'(sleep 2; ls -l) > out 2>err'
-            ]
-            action:[:osStatus | sema signal ].
-
-     sema wait.
-     Transcript showCR:'finished'
-    "
-
-    "
-     |pid sema|
-
-     sema := Semaphore new.
-
-     Processor
-            monitor:[
-                pid := OperatingSystem startProcess:'(sleep 1; echo 1; sleep 9; ls -l) > out 2>err'
-            ]
-            action:[:osStatus | sema signal ].
-
-     Delay waitForSeconds:2.
-     OperatingSystem terminateProcess:pid.
-     Transcript showCR:'terminated'
-    "
-
-    "Modified: / 21.3.1997 / 10:04:35 / dq"
-    "Modified: / 15.7.1997 / 16:03:51 / stefan"
-    "Modified: / 5.6.1998 / 19:03:51 / cg"
-    "Created: / 12.11.1998 / 14:39:20 / cg"
-!
-
-startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-    errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
-    environment:anEvironmentDictionary inDirectory:dir showWindow:ignoredHere
-
-    "start executing the OS command as specified by the argument, aCommandString
-     as a separate process; do not wait for the command to finish.
-     If aCommandString is a String, the commandString is passed to a shell for execution
-     - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
-     If aCommandString is an Array, the first element is the command to be executed,
-     and the other elements are the arguments to the command. No shell is invoked in this case.
-     The command gets stdIn, stdOut and stdErr assigned from the arguments;
-     each may be nil.
-     Return the processId if successful, nil otherwise.
-     Use #monitorPid:action: for synchronization and exec status return,
-     or #killProcess: to stop it."
-
-    ^ self
-        startProcess:aCommandString inputFrom:anExternalInStream outputTo:anExternalOutStream
-        errorTo:anExternalErrStream auxFrom:anAuxiliaryStream
-        environment:anEvironmentDictionary inDirectory:dir newPgrp:true showWindow:ignoredHere
 ! !
 
 !UnixOperatingSystem class methodsFor:'executing OS commands-queries'!
 
 commandAndArgsForOSCommand:aCommandStringOrArray
     "get a shell and shell arguments for command execution.
-     If aCommandString is a String, the commandString is passed to a shell for execution
+     If aCommandStringOrArray is a String, the commandString is passed to a shell for execution
      - see the description of 'sh -c' in your UNIX manual ('cmd.com' in your MSDOS manual).
-     If aCommandString is an Array, the first element is the command to be executed,
-     and the other elements are the arguments to the command. No shell is invoked in this case."
+     If aCommandStringOrArray is an Array, the first element is the command to be executed,
+     and the other elements are the arguments to the command. No shell is invoked in this case.
+     The third element is nil - here for windows compatibility (showWindow in windows)"
 
     aCommandStringOrArray isNonByteCollection ifTrue:[
-	"if an array is passed, the command string has already been parsed an no shell is invoked"
-	^ Array with:aCommandStringOrArray first with:aCommandStringOrArray.
+        "if an array is passed, the command string has already been parsed an no shell is invoked"
+        ^ Array with:aCommandStringOrArray first with:aCommandStringOrArray with:nil.
     ].
 
     "/
     "/ '/bin/sh -c <command>'
     "/
 
-    ^ Array with:'/bin/sh' with:(Array with:'sh' with:'-c' with:aCommandStringOrArray)
+    ^ Array with:'/bin/sh' with:(Array with:'sh' with:'-c' with:aCommandStringOrArray) with:nil.
 
     "Modified: / 20.1.1998 / 16:57:19 / md"
     "Modified: / 5.6.1998 / 17:40:48 / cg"
@@ -5392,40 +5139,40 @@
 %{
 #ifdef __SCHTEAM__
     if (encodedPathName.isStringLike()) {
-	java.io.File file = new java.io.File( encodedPathName.asString() );
-	int _mode;
-
-	if (file.exists() && file.isDirectory()) {
-	    return __c__._RETURN_true();
-	}
-	return __c__._RETURN_false();
+        java.io.File file = new java.io.File( encodedPathName.asString() );
+        int _mode;
+
+        if (file.exists() && file.isDirectory()) {
+            return __c__._RETURN_true();
+        }
+        return __c__._RETURN_false();
     }
 #else
     int ret;
 
     if (__isStringLike(encodedPathName)) {
-	struct stat buf;
+        struct stat buf;
 
 # ifdef TRACE_STAT_CALLS
-	printf("stat on '%s' for isDirectory\n", __stringVal(encodedPathName));
-# endif
-	__BEGIN_INTERRUPTABLE__
-	do {
-	    ret = stat((char *) __stringVal(encodedPathName), &buf);
-	} while ((ret < 0) && (errno == EINTR));
-	__END_INTERRUPTABLE__
-	if (ret < 0) {
-	    @global(LastErrorNumber) = __mkSmallInteger(errno);
-	    RETURN ( false );
-	}
-	RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
+        printf("stat on '%s' for isDirectory\n", __stringVal(encodedPathName));
+# endif
+        __BEGIN_INTERRUPTABLE__
+        do {
+            ret = stat((char *) __stringVal(encodedPathName), &buf);
+        } while ((ret < 0) && (errno == EINTR));
+        __END_INTERRUPTABLE__
+        if (ret < 0) {
+            @global(LastErrorNumber) = __mkSmallInteger(errno);
+            RETURN ( false );
+        }
+        RETURN ( ((buf.st_mode & S_IFMT) == S_IFDIR) ? true : false);
     }
 #endif /* not SCHTEAM */
 %}.
     ^ self primitiveFailed
 
     "an alternative implementation would be:
-	^ (self infoOf:aPathName) type == #directory
+        ^ (self infoOf:aPathName) type == #directory
     "
 !
 
--- a/Win32OperatingSystem.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/Win32OperatingSystem.st	Thu Jan 05 21:02:10 2017 +0000
@@ -4297,18 +4297,6 @@
     "Created: / 15-11-2016 / 19:39:49 / cg"
 !
 
-primExec:commandPath commandLine:commandLine fileDescriptors:fdArray fork:doFork newPgrp:newPgrp
-	inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
-	showWindow:showWindowBooleanOrNil
-    "obsolete internal lowLevel entry for combined fork & exec for WIN32"
-
-    ^ self
-	primExec:commandPath commandLine:commandLine environment:nil
-	fileDescriptors:fdArray fork:doFork newPgrp:newPgrp
-	inPath:dirName createFlags:flagsOrNil inheritHandles:inheritHandles
-	showWindow:showWindowBooleanOrNil
-!
-
 shellExecute:hwndArg lpOperation:lpOperationArg lpFile:lpFileArg lpParameters:lpParametersArg lpDirectory:lpDirectoryArg nShowCmd:nShowCmd
     "Opens or prints the specified file, which can be an executable, document file, or directory.
      If its a directory, an explorer window is opened (see example below).
--- a/abbrev.stc	Wed Dec 28 22:58:47 2016 +0000
+++ b/abbrev.stc	Thu Jan 05 21:02:10 2017 +0000
@@ -71,6 +71,7 @@
 CompiledCode CompiledCode stx:libbasic 'Kernel-Methods' 0
 ControlInterrupt ControlInterrupt stx:libbasic 'Kernel-Exceptions-Control' 1
 Date Date stx:libbasic 'Magnitude-Time' 0
+EventSemaphore EventSemaphore stx:libbasic 'Kernel-Processes' 0
 Exception Exception stx:libbasic 'Kernel-Exceptions' 1
 ExternalFunction ExternalFunction stx:libbasic 'System-Support' 0
 False False stx:libbasic 'Kernel-Objects' 0
@@ -87,7 +88,6 @@
 NoHandlerError NoHandlerError stx:libbasic 'Kernel-Exceptions-Errors' 1
 Notification Notification stx:libbasic 'Kernel-Exceptions' 1
 OSHandle OSHandle stx:libbasic 'Compatibility-VisualWorks' 0
-PCFilename PCFilename stx:libbasic 'OS-Windows' 0
 PeekableStream PeekableStream stx:libbasic 'Streams' 0
 Process Process stx:libbasic 'Kernel-Processes' 0
 QuerySignal QuerySignal stx:libbasic 'Kernel-Exceptions' 0
@@ -100,7 +100,6 @@
 True True stx:libbasic 'Kernel-Objects' 0
 UnixFilename UnixFilename stx:libbasic 'OS-Unix' 0
 WeakInterestConverter WeakInterestConverter stx:libbasic 'Interface-Support-Models' 0
-Win32Constants Win32Constants stx:libbasic 'OS-Windows' 0
 ArrayedCollection ArrayedCollection stx:libbasic 'Collections-Abstract' 0
 Association Association stx:libbasic 'Collections-Support' 0
 Block Block stx:libbasic 'Kernel-Methods' 0
@@ -170,7 +169,6 @@
 UserConfirmation UserConfirmation stx:libbasic 'Kernel-Exceptions-Notifications' 1
 UserInterrupt UserInterrupt stx:libbasic 'Kernel-Exceptions-Control' 1
 UserNotification UserNotification stx:libbasic 'Kernel-Exceptions-Notifications' 1
-Win32Handle Win32Handle stx:libbasic 'OS-Windows' 0
 YesToAllConfirmation YesToAllConfirmation stx:libbasic 'Kernel-Exceptions-Notifications' 1
 stx_libbasic stx_libbasic stx:libbasic '* Projects & Packages *' 3
 AbortAllOperationRequest AbortAllOperationRequest stx:libbasic 'Kernel-Exceptions-Control' 1
@@ -220,6 +218,9 @@
 TerminateProcessRequest TerminateProcessRequest stx:libbasic 'Kernel-Exceptions-Control' 1
 TimeDuration TimeDuration stx:libbasic 'Magnitude-Time' 0
 UninterpretedBytes UninterpretedBytes stx:libbasic 'Collections-Abstract' 0
+UnixFileDescriptorHandle UnixFileDescriptorHandle stx:libbasic 'OS-Unix' 0
+UnixFileHandle UnixFileHandle stx:libbasic 'OS-Unix' 0
+UnixOperatingSystem UnixOperatingSystem stx:libbasic 'OS-Unix' 0
 UserInformation UserInformation stx:libbasic 'Kernel-Exceptions-Notifications' 1
 UtcTimestamp UtcTimestamp stx:libbasic 'Magnitude-Time' 0
 VMInternalError VMInternalError stx:libbasic 'Kernel-Exceptions-Errors' 1
@@ -228,7 +229,6 @@
 WeakArray WeakArray stx:libbasic 'Collections-Weak' 0
 WeakIdentitySet WeakIdentitySet stx:libbasic 'Collections-Weak' 0
 WeakValueDictionary WeakValueDictionary stx:libbasic 'Collections-Weak' 0
-Win32FILEHandle Win32FILEHandle stx:libbasic 'OS-Windows' 0
 WriteStream WriteStream stx:libbasic 'Streams' 0
 AbortOperationRequest AbortOperationRequest stx:libbasic 'Kernel-Exceptions-Control' 1
 AbstractNumberVector AbstractNumberVector stx:libbasic 'Collections-Arrayed' 0
@@ -254,6 +254,7 @@
 LargeInteger LargeInteger stx:libbasic 'Magnitude-Numbers' 0
 LongFloat LongFloat stx:libbasic 'Magnitude-Numbers' 0
 OSSignalInterrupt OSSignalInterrupt stx:libbasic 'Kernel-Exceptions-Control' 1
+OSXOperatingSystem OSXOperatingSystem stx:libbasic 'OS-Unix' 0
 OsIllegalOperation OsIllegalOperation stx:libbasic 'OS-Support' 1
 OsInaccessibleError OsInaccessibleError stx:libbasic 'OS-Support' 1
 OsInvalidArgumentsError OsInvalidArgumentsError stx:libbasic 'OS-Support' 1
@@ -322,7 +323,6 @@
 UnimplementedFunctionalityError UnimplementedFunctionalityError stx:libbasic 'Kernel-Exceptions-Errors' 1
 UnprotectedExternalBytes UnprotectedExternalBytes stx:libbasic 'System-Support' 0
 WeakDependencyDictionary WeakDependencyDictionary stx:libbasic 'Collections-Weak' 0
-Win32OperatingSystem Win32OperatingSystem stx:libbasic 'OS-Windows' 0
 WriteError WriteError stx:libbasic 'Kernel-Exceptions-Errors' 1
 AbstractClassInstantiationError AbstractClassInstantiationError stx:libbasic 'Kernel-Exceptions-ExecutionErrors' 1
 BadLiteralsError BadLiteralsError stx:libbasic 'Kernel-Exceptions-ExecutionErrors' 1
@@ -373,10 +373,11 @@
 UnderflowError UnderflowError stx:libbasic 'Kernel-Exceptions-Errors' 1
 ZeroDivide ZeroDivide stx:libbasic 'Kernel-Exceptions-Errors' 1
 BadRomanNumberFormatError BadRomanNumberFormatError stx:libbasic 'Magnitude-Numbers' 1
-UnixFileDescriptorHandle UnixFileDescriptorHandle stx:libbasic  'unknownCategory'  0
-UnixFileHandle UnixFileHandle stx:libbasic  'unknownCategory'  0
-UnixOperatingSystem UnixOperatingSystem stx:libbasic  'unknownCategory'  0
-OSXOperatingSystem OSXOperatingSystem stx:libbasic  'unknownCategory'  0
+PCFilename PCFilename stx:libbasic  'unknownCategory'  0
+Win32Constants Win32Constants stx:libbasic  'unknownCategory'  0
+Win32Handle Win32Handle stx:libbasic  'unknownCategory'  0
+Win32FILEHandle Win32FILEHandle stx:libbasic  'unknownCategory'  0
+Win32OperatingSystem Win32OperatingSystem stx:libbasic  'unknownCategory'  0
 OpenVMSFileHandle OpenVMSFileHandle stx:libbasic  'unknownCategory'  0
 OpenVMSFilename OpenVMSFilename stx:libbasic  'unknownCategory'  0
 OpenVMSOperatingSystem OpenVMSOperatingSystem stx:libbasic  'unknownCategory'  0
--- a/bc.mak	Wed Dec 28 22:58:47 2016 +0000
+++ b/bc.mak	Thu Jan 05 21:02:10 2017 +0000
@@ -140,6 +140,7 @@
 $(OUTDIR)CompiledCode.$(O) CompiledCode.$(C) CompiledCode.$(H): CompiledCode.st $(INCLUDE_TOP)\stx\libbasic\ExecutableFunction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)ControlInterrupt.$(O) ControlInterrupt.$(C) ControlInterrupt.$(H): ControlInterrupt.st $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)Date.$(O) Date.$(C) Date.$(H): Date.st $(INCLUDE_TOP)\stx\libbasic\Magnitude.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
+$(OUTDIR)EventSemaphore.$(O) EventSemaphore.$(C) EventSemaphore.$(H): EventSemaphore.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\Semaphore.$(H) $(STCHDR)
 $(OUTDIR)Exception.$(O) Exception.$(C) Exception.$(H): Exception.st $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)ExternalFunction.$(O) ExternalFunction.$(C) ExternalFunction.$(H): ExternalFunction.st $(INCLUDE_TOP)\stx\libbasic\ExecutableFunction.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
 $(OUTDIR)False.$(O) False.$(C) False.$(H): False.st $(INCLUDE_TOP)\stx\libbasic\Boolean.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
@@ -437,10 +438,10 @@
 $(OUTDIR)UnderflowError.$(O) UnderflowError.$(C) UnderflowError.$(H): UnderflowError.st $(INCLUDE_TOP)\stx\libbasic\ArithmeticError.$(H) $(INCLUDE_TOP)\stx\libbasic\Error.$(H) $(INCLUDE_TOP)\stx\libbasic\Exception.$(H) $(INCLUDE_TOP)\stx\libbasic\ExecutionError.$(H) $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProceedableError.$(H) $(INCLUDE_TOP)\stx\libbasic\RangeError.$(H) $(STCHDR)
 $(OUTDIR)ZeroDivide.$(O) ZeroDivide.$(C) ZeroDivide.$(H): ZeroDivide.st $(INCLUDE_TOP)\stx\libbasic\ArithmeticError.$(H) $(INCLUDE_TOP)\stx\libbasic\DomainError.$(H) $(INCLUDE_TOP)\stx\libbasic\Error.$(H) $(INCLUDE_TOP)\stx\libbasic\Exception.$(H) $(INCLUDE_TOP)\stx\libbasic\ExecutionError.$(H) $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProceedableError.$(H) $(STCHDR)
 $(OUTDIR)BadRomanNumberFormatError.$(O) BadRomanNumberFormatError.$(C) BadRomanNumberFormatError.$(H): BadRomanNumberFormatError.st $(INCLUDE_TOP)\stx\libbasic\ConversionError.$(H) $(INCLUDE_TOP)\stx\libbasic\Error.$(H) $(INCLUDE_TOP)\stx\libbasic\Exception.$(H) $(INCLUDE_TOP)\stx\libbasic\GenericException.$(H) $(INCLUDE_TOP)\stx\libbasic\NumberConversionError.$(H) $(INCLUDE_TOP)\stx\libbasic\NumberFormatError.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\ProceedableError.$(H) $(INCLUDE_TOP)\stx\libbasic\RomanNumberFormatError.$(H) $(STCHDR)
-$(OUTDIR)PCFilename.$(O) PCFilename.$(C) PCFilename.$(H): PCFilename.st $(INCLUDE_TOP)\stx\libbasic\Filename.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)Win32Constants.$(O) Win32Constants.$(C) Win32Constants.$(H): Win32Constants.st $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(STCHDR)
-$(OUTDIR)Win32FILEHandle.$(O) Win32FILEHandle.$(C) Win32FILEHandle.$(H): Win32FILEHandle.st $(INCLUDE_TOP)\stx\libbasic\ExternalAddress.$(H) $(INCLUDE_TOP)\stx\libbasic\OSFileHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\OSHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)Win32Handle.$(O) Win32Handle.$(C) Win32Handle.$(H): Win32Handle.st $(INCLUDE_TOP)\stx\libbasic\ExternalAddress.$(H) $(INCLUDE_TOP)\stx\libbasic\OSHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(STCHDR)
-$(OUTDIR)Win32OperatingSystem.$(O) Win32OperatingSystem.$(C) Win32OperatingSystem.$(H): Win32OperatingSystem.st $(INCLUDE_TOP)\stx\libbasic\AbstractOperatingSystem.$(H) $(INCLUDE_TOP)\stx\libbasic\ArrayedCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\ByteArray.$(H) $(INCLUDE_TOP)\stx\libbasic\Collection.$(H) $(INCLUDE_TOP)\stx\libbasic\ExternalAddress.$(H) $(INCLUDE_TOP)\stx\libbasic\OSHandle.$(H) $(INCLUDE_TOP)\stx\libbasic\Object.$(H) $(INCLUDE_TOP)\stx\libbasic\SequenceableCollection.$(H) $(INCLUDE_TOP)\stx\libbasic\SharedPool.$(H) $(INCLUDE_TOP)\stx\libbasic\UninterpretedBytes.$(H) $(INCLUDE_TOP)\stx\libbasic\Win32Constants.$(H) $(INCLUDE_TOP)\stx\libbasic\Win32Handle.$(H) $(STCHDR)
+$(OUTDIR)PCFilename.$(O) PCFilename.$(C) PCFilename.$(H): PCFilename.st $(STCHDR)
+$(OUTDIR)Win32Constants.$(O) Win32Constants.$(C) Win32Constants.$(H): Win32Constants.st $(STCHDR)
+$(OUTDIR)Win32Handle.$(O) Win32Handle.$(C) Win32Handle.$(H): Win32Handle.st $(STCHDR)
+$(OUTDIR)Win32FILEHandle.$(O) Win32FILEHandle.$(C) Win32FILEHandle.$(H): Win32FILEHandle.st $(STCHDR)
+$(OUTDIR)Win32OperatingSystem.$(O) Win32OperatingSystem.$(C) Win32OperatingSystem.$(H): Win32OperatingSystem.st $(STCHDR)
 
 # ENDMAKEDEPEND --- do not remove this line
--- a/libInit.cc	Wed Dec 28 22:58:47 2016 +0000
+++ b/libInit.cc	Thu Jan 05 21:02:10 2017 +0000
@@ -86,6 +86,7 @@
 extern void _CompiledCode_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _ControlInterrupt_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _Date_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
+extern void _EventSemaphore_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _Exception_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _ExternalFunction_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
 extern void _False_Init(int pass, struct __vmData__ *__pRT__, OBJ snd);
@@ -484,6 +485,7 @@
     _CompiledCode_Init(pass,__pRT__,snd);
     _ControlInterrupt_Init(pass,__pRT__,snd);
     _Date_Init(pass,__pRT__,snd);
+    _EventSemaphore_Init(pass,__pRT__,snd);
     _Exception_Init(pass,__pRT__,snd);
     _ExternalFunction_Init(pass,__pRT__,snd);
     _False_Init(pass,__pRT__,snd);
--- a/stx_libbasic.st	Wed Dec 28 22:58:47 2016 +0000
+++ b/stx_libbasic.st	Thu Jan 05 21:02:10 2017 +0000
@@ -248,6 +248,7 @@
         CompiledCode
         ControlInterrupt
         Date
+        EventSemaphore
         Exception
         ExternalFunction
         False
@@ -264,7 +265,6 @@
         NoHandlerError
         Notification
         OSHandle
-        (PCFilename win32)
         PeekableStream
         Process
         QuerySignal
@@ -277,7 +277,6 @@
         True
         UnixFilename
         WeakInterestConverter
-        (Win32Constants win32)
         ArrayedCollection
         Association
         Block
@@ -347,7 +346,6 @@
         UserConfirmation
         UserInterrupt
         UserNotification
-        (Win32Handle win32)
         YesToAllConfirmation
         #'stx_libbasic'
         AbortAllOperationRequest
@@ -397,6 +395,9 @@
         TerminateProcessRequest
         TimeDuration
         UninterpretedBytes
+        (UnixFileDescriptorHandle unix)
+        (UnixFileHandle unix)
+        (UnixOperatingSystem unix)
         UserInformation
         UtcTimestamp
         VMInternalError
@@ -405,7 +406,6 @@
         WeakArray
         WeakIdentitySet
         WeakValueDictionary
-        (Win32FILEHandle win32)
         WriteStream
         AbortOperationRequest
         AbstractNumberVector
@@ -431,6 +431,7 @@
         LargeInteger
         LongFloat
         OSSignalInterrupt
+        (OSXOperatingSystem unix)
         OsIllegalOperation
         OsInaccessibleError
         OsInvalidArgumentsError
@@ -499,7 +500,6 @@
         UnimplementedFunctionalityError
         UnprotectedExternalBytes
         WeakDependencyDictionary
-        (Win32OperatingSystem win32)
         WriteError
         AbstractClassInstantiationError
         BadLiteralsError
@@ -550,10 +550,11 @@
         UnderflowError
         ZeroDivide
         BadRomanNumberFormatError
-        (UnixFileDescriptorHandle unix)
-        (UnixFileHandle unix)
-        (UnixOperatingSystem unix)
-        (OSXOperatingSystem unix)
+        (PCFilename win32)
+        (Win32Constants win32)
+        (Win32Handle win32)
+        (Win32FILEHandle win32)
+        (Win32OperatingSystem win32)
         (OpenVMSFileHandle vms)
         (OpenVMSFilename vms)
         (OpenVMSOperatingSystem vms)
--- a/stx_libbasicWINrc.rc	Wed Dec 28 22:58:47 2016 +0000
+++ b/stx_libbasicWINrc.rc	Thu Jan 05 21:02:10 2017 +0000
@@ -3,7 +3,7 @@
 // automagically generated from the projectDefinition: stx_libbasic.
 //
 VS_VERSION_INFO VERSIONINFO
-  FILEVERSION     7,1,1,170
+  FILEVERSION     7,1,1,171
   PRODUCTVERSION  7,1,0,0
 #if (__BORLANDC__)
   FILEFLAGSMASK   VS_FF_DEBUG | VS_FF_PRERELEASE
@@ -20,12 +20,12 @@
     BEGIN
       VALUE "CompanyName", "Claus Gittinger / eXept Software AG\0"
       VALUE "FileDescription", "Smalltalk/X Basic Classes (LIB)\0"
-      VALUE "FileVersion", "7.1.1.170\0"
+      VALUE "FileVersion", "7.1.1.171\0"
       VALUE "InternalName", "stx:libbasic\0"
       VALUE "LegalCopyright", "Copyright Claus Gittinger 1988\nCopyright eXept Software AG 2013\0"
       VALUE "ProductName", "Smalltalk/X\0"
       VALUE "ProductVersion", "7.1.0.0\0"
-      VALUE "ProductDate", "Thu, 22 Dec 2016 13:56:45 GMT\0"
+      VALUE "ProductDate", "Tue, 27 Dec 2016 10:27:37 GMT\0"
     END
 
   END