'From Squeak5.3alpha of 15 September 2019 [latest update: #18906] on 16 September 2019 at 5:19:15 pm'!
CodeHolder subclass: #Debugger
	instanceVariableNames: 'interruptedProcess contextStack contextStackIndex contextStackList receiverInspector contextVariablesInspector externalInterrupt proceedValue selectingPC savedCursor isolationHead failedProject labelString message untilExpression '
	classVariableNames: 'ContextStackKeystrokes ErrorRecursion ErrorRecursionGuard ErrorReportServer InterruptUIProcessIfBlockedOnErrorInBackgroundProcess SavedExtent WantsAnnotationPane '
	poolDictionaries: ''
	category: 'Tools-Debugger'!
Debugger subclass: #MVCDebugger
	instanceVariableNames: 'interruptedController'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'ST80-Support'!
Debugger subclass: #MorphicDebugger
	instanceVariableNames: 'errorWasInUIProcess'
	classVariableNames: ''
	poolDictionaries: ''
	category: 'Morphic-Support'!

!Object methodsFor: '*60Deprecated-Tools' stamp: 'mt 9/16/2019 12:07'!
notifyWithLabel: aString 
	"Create and schedule a Notifier with aString as the window label as well as the contents of the window, in  order to request confirmation before a process can proceed."

	self deprecated.
	self notify: aString.
	
	"nil notify: 'let us see if this works'"! !


!Debugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 16:03'!
context: aContext

	self
		process: Processor activeProcess
		context: aContext.! !

!Debugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 15:05'!
initialize

	super initialize.

	Smalltalk at: #MessageTally ifPresentAndInMemory: [ :tally |
		tally terminateTimerProcess].

	externalInterrupt := false.
	selectingPC := true.! !

!Debugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 14:54'!
openNotifierContents: msgString label: label
	"Create, schedule and answer a notifier view with the given label and message. A notifier view shows just the message or the first several lines of the stack, with a menu that allows the user to open a full debugger if so desired."
	"NOTE: When this method returns, a new process has been scheduled to run the windows, and thus this notifier, but the previous active process has not been suspended.  The sender will do this."
	| msg builder spec |

	Sensor flushKeyboard.
	savedCursor := Cursor currentCursor.
	Cursor currentCursor: Cursor normal.
	msg := (label beginsWith: 'Space is low')
		ifTrue: [self lowSpaceChoices, (msgString ifNil: [String empty])]
		ifFalse: [msgString].
	builder := ToolBuilder default.
	spec := self buildNotifierWith: builder label: label message: msg.
	self expandStack.
	^ builder openDebugger: spec! !

!Debugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 14:06'!
process: aProcess context: aContext

	interruptedProcess := aProcess.

	self newStack: (aContext stackOfSize: 1).
	contextStackIndex := 1.! !

!Debugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 17:09'!
windowIsClosing
	"My window is being closed; clean up. Restart the low space watcher."

	interruptedProcess == nil ifTrue: [^ self].
	interruptedProcess terminate.
	interruptedProcess := nil.
	
	contextStack := nil.
	receiverInspector := nil.
	contextVariablesInspector := nil.
	Smalltalk installLowSpaceWatcher.  "restart low space handler"
! !

!Debugger methodsFor: 'private' stamp: 'mt 9/16/2019 14:39'!
resumeProcess: aTopView

	self subclassResponsibility.! !


!Debugger class methodsFor: 'instance creation' stamp: 'mt 9/16/2019 13:59'!
informExistingDebugger: aContext label: aString
	"Walking the context chain, we try to find out if we're in a debugger stepping situation.
	 If we find the relevant contexts, we must rearrange them so they look just like they would
	 if the methods were executed outside of the debugger.
	 hmm 8/3/2001 13:05"
	| ctx quickStepMethod oldSender baseContext |
	ctx := thisContext.
	quickStepMethod := Context
							compiledMethodAt: #quickSend:to:with:lookupIn:
							ifAbsent: [Context compiledMethodAt: #quickSend:to:with:super:].
	[ctx sender == nil or: [ctx sender method == quickStepMethod]] whileFalse:
		[ctx := ctx sender].
	ctx sender ifNil: [^self].
	baseContext := ctx.
	"baseContext is now the context created by the #quickSend... method."
	oldSender := ctx := ctx sender home sender.
	"oldSender is the context which originally sent the #quickSend... method"
	[ctx == nil or: [(ctx objectClass: ctx receiver) includesBehavior: self]] whileFalse:
		[ctx := ctx sender].
	ctx ifNil: [^self].
	"ctx is the context of the Debugger method #doStep"
	ctx receiver
		labelString: aString;
		externalInterrupt: false;
		proceedValue: aContext receiver.
	baseContext swapSender: baseContext sender sender sender.	"remove intervening contexts"
	thisContext swapSender: oldSender.	"make myself return to debugger"
	^ aContext! !

!Debugger class methodsFor: '*System-opening' stamp: 'mt 9/16/2019 14:42'!
openInterrupt: aString onProcess: interruptedProcess

	^ Project current debuggerClass
		openInterrupt: aString onProcess: interruptedProcess! !

!Debugger class methodsFor: '*System-opening' stamp: 'mt 9/16/2019 14:42'!
openOn: process context: context label: title contents: contentsStringOrNil fullView: bool

	^ Project current debuggerClass
		openOn: process context: context label: title contents: contentsStringOrNil fullView: bool! !

!Debugger class methodsFor: '*System-opening' stamp: 'mt 9/16/2019 14:42'!
openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil

	^ Project current debuggerClass
		openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil! !

!Debugger class methodsFor: '*60Deprecated-opening' stamp: 'mt 9/16/2019 14:49'!
context: aContext 

	self deprecated.

	^ self
		openOn: Processor activeProcess
		context: aContext
		label: 'Debug'
		contents: nil
		fullView: false! !

!Debugger class methodsFor: '*60Deprecated-opening' stamp: 'mt 9/16/2019 14:00'!
openContext: aContext label: aString contents: contentsStringOrNil 
	
	self deprecated.
	
	^ self
		openOn: Processor activeProcess
		context: aContext
		label: aString
		contents: contentsStringOrNil
		fullView: false
! !


!FilePackage methodsFor: '*UpdateStream-conflict checker' stamp: 'mt 9/16/2019 12:06'!
conflictsWithUpdatedMethods
	"Check this package for conflicts with methods in the image which are in newer updates."

	| localFileName stream updateNumberString updateNumber imageUpdateNumber updateNumberChangeSet conflicts fileStream |

	localFileName := FileDirectory localNameFor: fullName.
	stream := ReadStream on: sourceSystem.
	stream upToAll: 'latest update: #'.
	updateNumberString := stream upTo: $].
	stream close.
	
	fileStream := FileStream readOnlyFileNamed: fullName.
	(fileStream contentsOfEntireFile includes: Character linefeed)
		ifTrue: [self notify:  'The changeset file ', localFileName, ' contains linefeeds.  Proceed if...
you know that this is okay (e.g. the file contains raw binary data).'].
	fileStream close.

	updateNumberString isEmpty ifFalse:		"remove prepended junk, if any"
		[updateNumberString := (updateNumberString findTokens: Character space) last].
	updateNumberString asInteger ifNil:
		[(self confirm: 'Error: ', localFileName, ' has no valid Latest Update number in its header.
Do you want to enter an update number for this file?')
			ifFalse: [^ self]
			ifTrue: [updateNumberString := UIManager default
						request: 'Please enter the estimated update number (e.g. 4332).']].
	updateNumberString asInteger ifNil: [self inform: 'Conflict check cancelled.'. ^ self].
	updateNumber := updateNumberString asInteger.

	imageUpdateNumber := SystemVersion current highestUpdate.
	updateNumber > imageUpdateNumber ifTrue:
		[(self confirm: 'Warning: The update number for this file (#', updateNumberString, ')
is greater than the highest update number for this image (#', imageUpdateNumber asString, ').
This probably means you need to update your image.
Should we proceed anyway as if the file update number is #', imageUpdateNumber asString, '?')
			ifTrue:
				[updateNumber := imageUpdateNumber.
				updateNumberString := imageUpdateNumber asString]
			ifFalse: [^ self]].

	updateNumberChangeSet := self findUpdateChangeSetMatching: updateNumber.
	updateNumberChangeSet ifNil: [^ self].

	Smalltalk isMorphic ifTrue: [self currentWorld findATranscript: self currentEvent].
	self class logCr; logCr; log: 'Checking ', localFileName, ' (#', updateNumberString, ') for method conflicts with changesets after ', updateNumberChangeSet name, ' ...'.

	conflicts := OrderedCollection new.
	self classes do: [:pseudoClass |
		(Array with: pseudoClass with: pseudoClass metaClass) do: [:classOrMeta |
			classOrMeta selectorsDo: [:selector | | conflict |
				conflict := self
							checkForMoreRecentUpdateThanChangeSet: updateNumberChangeSet
							pseudoClass: classOrMeta
							selector: selector.
				conflict ifNotNil: [conflicts add: conflict].
			].
		].
	].
	self class logCr; log: conflicts size asString, (' conflict' asPluralBasedOn: conflicts), ' found.'; logCr.
	self class closeLog.
	^ conflicts! !


!MVCDebugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 16:03'!
context: aContext

	self
		process: Processor activeProcess
		controller: (ScheduledControllers inActiveControllerProcess
						ifTrue: [ScheduledControllers activeController])
		context: aContext.! !

!MVCDebugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 16:02'!
process: aProcess controller: aController context: aContext

	self process: aProcess context: aContext.
	
	interruptedController := aController.! !

!MVCDebugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 17:09'!
windowIsClosing

	super windowIsClosing.
	
	interruptedController := nil.! !

!MVCDebugger methodsFor: 'private' stamp: 'mt 9/16/2019 11:54'!
resumeProcess: aTopView 

	aTopView erase.
	savedCursor
		ifNotNil: [Cursor currentCursor: savedCursor].
	interruptedProcess isTerminated ifFalse: [
		ScheduledControllers activeControllerNoTerminate: interruptedController andProcess: interruptedProcess].
	"if old process was terminated, just terminate current one"
	interruptedProcess := nil. "Before delete, so release doesn't terminate it"
	aTopView controller closeAndUnscheduleNoErase.
	Smalltalk installLowSpaceWatcher. "restart low space handler"
	Processor terminateActive
! !


!MVCDebugger class methodsFor: 'opening' stamp: 'mt 9/16/2019 14:02'!
openInterrupt: aString onProcess: interruptedProcess
	"Open a notifier in response to an interrupt. An interrupt occurs when the user types the interrupt key (cmd-. on Macs, ctrl-c or alt-. on other systems) or when the low-space watcher detects that memory is low."
	
	| debugger |
	<primitive: 19> "Simulation guard"
	debugger := self new.
	debugger
		process: interruptedProcess
		controller: (ScheduledControllers inActiveControllerProcess == interruptedProcess
						ifTrue: [ScheduledControllers activeController])
		context: interruptedProcess suspendedContext.
	debugger externalInterrupt: true.

	Preferences logDebuggerStackToFile ifTrue:
		[(aString includesSubstring: 'Space') & (aString includesSubstring: 'low')
			ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
			"logging disabled for 4.3 release, see
				http://lists.squeak.org/pipermail/squeak-dev/2011-December/162503.html"
			"ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]"].

	Preferences eToyFriendly ifTrue: [Project current world stopRunningAll].
	^debugger
		openNotifierContents: nil label: aString;
		yourself
! !

!MVCDebugger class methodsFor: 'opening' stamp: 'mt 9/16/2019 14:10'!
openOn: process context: context label: title contents: contentsStringOrNil fullView: bool
	"Open a notifier in response to an error, halt, or notify. A notifier view just shows a short view of the sender stack and provides a menu that lets the user open a full debugger."

	| controller debugger |
	controller := ScheduledControllers activeControllerProcess == process
				ifTrue: [ScheduledControllers activeController].
	[Preferences logDebuggerStackToFile
		ifTrue: [Smalltalk logSqueakError: title inContext: context]] on: Error do: [:ex | ex return: nil].
	[debugger := self new
				process: process
				controller: controller
				context: context.
	bool
		ifTrue: [debugger openFullNoSuspendLabel: title]
		ifFalse: [debugger openNotifierContents: contentsStringOrNil label: title].
	] on: Error do: [:ex |
			self primitiveError: 'Original error: ' , title asString , '.
			Debugger error: ' , ([ex description]
							on: Error
							do: ['a ' , ex class printString]) , ':'].
	process suspend! !

!MVCDebugger class methodsFor: 'opening' stamp: 'mt 9/16/2019 14:28'!
openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil

	| guineaPig debugger debuggerWindow context |
	guineaPig :=
		[aCompiledMethod
			valueWithReceiver: anObject
			 arguments: (aContextOrNil ifNil: [ #() ] ifNotNil: [ { aContextOrNil } ]).
		 guineaPig := nil "spot the return from aCompiledMethod"] newProcess.
	context := guineaPig suspendedContext.
	debugger := self new
		process: guineaPig
		controller: (ScheduledControllers inActiveControllerProcess ifTrue:
						[ScheduledControllers activeController])
		context: context.
	debuggerWindow := debugger openFullNoSuspendLabel: 'Debug it'.
	"Now step into the expression.  But if it is quick (is implemented as a primtiive, e.g. `0')
	 it will return immediately back to the block that is sent newProcess above.  Guard
	 against that with the check for home being thisContext."
	[debugger interruptedContext method == aCompiledMethod]
		whileFalse:
			[(guineaPig isNil
			  and: [debugger interruptedContext home == thisContext]) ifTrue:
				[debuggerWindow controller closeAndUnschedule.
				 UIManager default inform: 'Nothing to debug; expression is optimized'.
				 ^self].
			debugger send]! !


!MorphicDebugger methodsFor: 'accessing' stamp: 'mt 9/16/2019 15:06'!
errorWasInUIProcess

	^ errorWasInUIProcess! !

!MorphicDebugger methodsFor: 'accessing' stamp: 'mt 9/16/2019 15:06'!
errorWasInUIProcess: boolean

	errorWasInUIProcess := boolean! !

!MorphicDebugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 14:06'!
initialize

	super initialize.
	
	errorWasInUIProcess := false.! !

!MorphicDebugger methodsFor: 'initialize' stamp: 'mt 9/16/2019 17:10'!
windowIsClosing
	"Keep track of last debugger extent."

	interruptedProcess ifNil: [ ^ self ].

	SavedExtent ifNotNil:
		[ self dependents
			detect:
				[ : each | each isWindowForModel: self ]
			ifFound:
				[ : topWindow | | isDebuggerNotNotifier |
				isDebuggerNotNotifier := self dependents anySatisfy:
					[ : each | each isTextView ].
				isDebuggerNotNotifier ifTrue: [
					SavedExtent := (topWindow extent / RealEstateAgent scaleFactor) rounded ] ]
			ifNone: [ "do nothing" ] ].

	super windowIsClosing.! !

!MorphicDebugger methodsFor: 'private' stamp: 'mt 9/16/2019 11:58'!
resumeProcess: debuggerWindow 

	| processToResume |
	processToResume := interruptedProcess.
	
	interruptedProcess := nil. "Before delete, so release doesn't terminate it"
	debuggerWindow delete.
	
	Project current world displayWorld. "We have to redraw *before* resuming the old process."
	Smalltalk installLowSpaceWatcher. "restart low space handler"

	savedCursor
		ifNotNil: [Cursor currentCursor: savedCursor].
	processToResume isTerminated ifFalse: [
		errorWasInUIProcess
					ifTrue: [Project resumeProcess: processToResume]
					ifFalse: [processToResume resume]].
	"if old process was terminated, just terminate current one"
	errorWasInUIProcess == false
		ifFalse: [Processor terminateActive]! !


!MorphicDebugger class methodsFor: 'opening' stamp: 'mt 9/16/2019 15:00'!
openDrawingErrors: errors
	"Open debuggers for all different errors found."
	
	self setErrorRecursion.
	errors do: [:processToLabel |
			(MorphicDebugger new process: processToLabel key context: processToLabel key suspendedContext)
				errorWasInUIProcess: Processor activeProcess = Project current uiProcess;
				openNotifierContents: nil label: processToLabel value].

	"Try to draw the debuggers or else there will be no chance to escape from this catch-drawing-error loop."
	Project current world displayWorld.
	self clearErrorRecursion.! !

!MorphicDebugger class methodsFor: 'opening' stamp: 'mt 9/16/2019 14:54'!
openInterrupt: aString onProcess: interruptedProcess
	"Open a notifier in response to an interrupt. An interrupt occurs when the user types the interrupt key (cmd-. on Macs, ctrl-c or alt-. on other systems) or when the low-space watcher detects that memory is low."

	| errorWasInUIProcess debugger |
	<primitive: 19> "Simulation guard"
	
	errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: interruptedProcess.
	debugger := self new.
	debugger
		process: interruptedProcess
		context: interruptedProcess suspendedContext.
	debugger
		externalInterrupt: true;
		errorWasInUIProcess: errorWasInUIProcess.

	Preferences logDebuggerStackToFile ifTrue:
		[(aString includesSubstring: 'Space') & (aString includesSubstring: 'low')
			ifTrue: [Smalltalk logError: aString inContext: debugger interruptedContext to: 'LowSpaceDebug.log']
			"logging disabled for 4.3 release, see
				http://lists.squeak.org/pipermail/squeak-dev/2011-December/162503.html"
			"ifFalse: [Smalltalk logSqueakError: aString inContext: debugger interruptedContext]"].

	Preferences eToyFriendly ifTrue: [Project current world stopRunningAll].
	^debugger
		openNotifierContents: nil label: aString;
		yourself
! !

!MorphicDebugger class methodsFor: 'opening' stamp: 'mt 9/16/2019 14:10'!
openOn: process context: context label: title contents: contentsStringOrNil fullView: full 
	"Open a notifier in response to an error, halt, or notify. A notifier view just shows a short view of the sender stack and provides a menu that lets the user open a full debugger."
	
	ErrorRecursionGuard critical: [
		
		| errorWasInUIProcess debugger |
		ErrorRecursion ifTrue: [
			"self assert: process == Project current uiProcess -- DOCUMENTATION ONLY"
			self clearErrorRecursion.
			^ Project current handleFatalDrawingError: title].
		
		[ErrorRecursion not & Preferences logDebuggerStackToFile
			ifTrue: [Smalltalk logSqueakError: title inContext: context]]
				on: Error
				do: [:ex | ex return: nil].
		
		errorWasInUIProcess := Project current spawnNewProcessIfThisIsUI: process.
		
		"Schedule debugging in deferred UI message because
			1) If process is the current UI process, it is already broken.
			2) If process is some other process, it must not execute UI code"
		Project current addDeferredUIMessage: [
			self setErrorRecursion.
			
			self informExistingDebugger: context label: title.
			
			debugger := self new process: process context: context.
			full
				ifTrue: [debugger openFullNoSuspendLabel: title]
				ifFalse: [debugger openNotifierContents: contentsStringOrNil label: title].
			debugger errorWasInUIProcess: errorWasInUIProcess.
		
			"Try drawing the debugger tool at least once to avoid freeze."
			Project current world displayWorldSafely.
			
			self clearErrorRecursion]].
	
	process suspend.! !

!MorphicDebugger class methodsFor: 'opening' stamp: 'mt 9/16/2019 14:29'!
openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContextOrNil

	| guineaPig debugger debuggerWindow context |
	guineaPig :=
		[aCompiledMethod
			valueWithReceiver: anObject
			 arguments: (aContextOrNil ifNil: [ #() ] ifNotNil: [ { aContextOrNil } ]).
		 guineaPig := nil "spot the return from aCompiledMethod"] newProcess.
	context := guineaPig suspendedContext.
	debugger := self new
		process: guineaPig
		context: context.
	debuggerWindow := debugger openFullNoSuspendLabel: 'Debug it'.
	"Now step into the expression.  But if it is quick (is implemented as a primtiive, e.g. `0')
	 it will return immediately back to the block that is sent newProcess above.  Guard
	 against that with the check for home being thisContext."
	[debugger interruptedContext method == aCompiledMethod]
		whileFalse:
			[(guineaPig isNil
			  and: [debugger interruptedContext home == thisContext]) ifTrue:
				[debuggerWindow delete.
				 UIManager default inform: 'Nothing to debug; expression is optimized'.
				 ^self].
			debugger send]! !


!ObjectTracer methodsFor: 'very few messages' stamp: 'mt 9/16/2019 13:40'!
doesNotUnderstand: aMessage 
	"All external messages (those not caused by the re-send) get trapped here"
	"Present a dubugger before proceeding to re-send the message"

	Warning signal: 'About to perform: ', aMessage selector.
	^ aMessage sentTo: tracedObject.
! !


!Process methodsFor: 'debugging' stamp: 'mt 9/16/2019 14:21'!
debug: context title: title full: bool

	self
		debug: context
		title: title
		full: bool
		contents: nil! !

!Process methodsFor: 'debugging' stamp: 'mt 9/16/2019 14:20'!
debug: context title: title full: bool contents: contents
	"Open debugger on self with context shown on top"

	| topCtxt |
	topCtxt := self isActiveProcess ifTrue: [thisContext] ifFalse: [self suspendedContext].
	(topCtxt hasContext: context) ifFalse: [^ self error: 'context not in process'].
	ToolSet debug: self context: context label: title contents: contents fullView: bool.! !


!Project methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 14:17'!
debuggerClass

	^ self subclassResponsibility! !

!Project methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 16:38'!
syntaxError: aSyntaxErrorNotification

	^ ToolSet editSyntaxError: aSyntaxErrorNotification! !


!MVCProject methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 14:17'!
debuggerClass

	^ Smalltalk classNamed: #MVCDebugger! !

!MVCProject methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 11:30'!
interruptName: labelString preemptedProcess: theInterruptedProcess
	"Create a Notifier on the interrupted process with the given label. Make the Notifier the active controller."

	theInterruptedProcess suspend.

	(world activeController ~~ nil and: [world activeController ~~ world screenController]) ifTrue: [
		theInterruptedProcess == self uiProcess
			ifTrue: [
				"Carefully de-emphasis the current window."
				world activeController view topView deEmphasizeForDebugger]
			ifFalse: [
				world activeController controlTerminate]].

	"This will just scheduleNoTerminate the newly built controller"
	ToolSet
		debugInterruptedProcess: theInterruptedProcess
		label: labelString.

	world searchForActiveController.! !

!MVCProject methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 16:58'!
syntaxError: aSyntaxErrorNotification

	super syntaxError: aSyntaxErrorNotification.
	Cursor normal show.
	Processor activeProcess suspend.! !


!MorphicProject methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 11:23'!
addDeferredUIMessage: valuableObject 
	"Arrange for valuableObject to be evaluated at a time when the user interface
	is in a coherent state."

	self flag: #discuss. "mt: Why are deferred UI messages shared among all Morphic projects? That's not the case for MVC projects..."
	WorldState addDeferredUIMessage: valuableObject! !

!MorphicProject methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 14:18'!
debuggerClass

	^ Smalltalk classNamed: #MorphicDebugger! !

!MorphicProject methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 11:30'!
interruptName: labelString preemptedProcess: theInterruptedProcess
	"Create a Notifier on the active scheduling process with the given label."

	| preemptedProcess projectProcess |
	ActiveHand ifNotNil:[ActiveHand interrupted].
	ActiveWorld := world. "reinstall active globals"
	ActiveHand := world primaryHand.
	ActiveHand interrupted. "make sure this one's interrupted too"
	ActiveEvent := nil.

	projectProcess := self uiProcess.	"we still need the accessor for a while"
	preemptedProcess := theInterruptedProcess ifNil: [Processor preemptedProcess].
	"Only debug preempted process if its priority is >= projectProcess' priority"
	preemptedProcess priority < projectProcess priority 
		ifTrue:[preemptedProcess := projectProcess].
	preemptedProcess suspend.
	
	ToolSet
		debugInterruptedProcess: preemptedProcess
		label: labelString.! !

!MorphicProject methodsFor: 'scheduling & debugging' stamp: 'mt 9/16/2019 16:48'!
syntaxError: aSyntaxErrorNotification

	| compilerProcess errorWasInUIProcess debugger |
	debugger := (super syntaxError: aSyntaxErrorNotification) model debugger.
	
	compilerProcess := Processor activeProcess.
	errorWasInUIProcess := self spawnNewProcessIfThisIsUI: compilerProcess.
	
	debugger errorWasInUIProcess: errorWasInUIProcess.
	compilerProcess suspend.! !


!Project class methodsFor: '*Etoys-Squeakland-utilities' stamp: 'mt 9/16/2019 14:16'!
interruptName: labelString preemptedProcess: theInterruptedProcess
	"Create a Notifier on the active scheduling process with the given label."
	
	Project current
		interruptName: labelString preemptedProcess: theInterruptedProcess! !


!ServerDirectory methodsFor: '*UpdateStream-updating' stamp: 'mt 9/16/2019 12:06'!
putUpdate: fileStrm
	"Put this file out as an Update on the servers of my group.  Each version of the system may have its own set of update files, or they may all share the same files.  'updates.list' holds the master list.  Each update is a fileIn whose name begins with a number.  See Utilities class readServerUpdatesThrough:saveLocally:updateImage:.
	When two sets of updates are stored on the same directory, one of them has a * in its 
serverUrls description.  When that is true, the first word of the description is put on
the front of 'updates.list', and that index file is used."

	| myServers updateStrm newName response localName seq indexPrefix listContents version versIndex lastNum stripped |
	localName := fileStrm localName.
	fileStrm size = 0 ifTrue:
		[^ self inform: 'That file has zero bytes!!  May have a new name.'].
	(fileStrm contentsOfEntireFile includes: Character linefeed)
		ifTrue: [self notify:  'That file contains linefeeds.  Proceed if...
you know that this is okay (e.g. the file contains raw binary data).'].
	fileStrm reset.
	(self checkNames: {localName}) ifFalse: [^ nil].	"illegal characters"
	response := UIManager default chooseFrom: #('Install update' 'Cancel update')
		title: 'Do you really want to broadcast the file ', localName, 
			'\to every Squeak user who updates from ' withCRs, self groupName, '?'.
	response = 1 ifFalse: [^ nil].	"abort"

	self openGroup.
	indexPrefix := (self groupName includes: $*) 
		ifTrue: [(self groupName findTokens: ' ') first]	"special for internal updates"
		ifFalse: ['']. 	"normal"
	myServers := self checkServersWithPrefix: indexPrefix
					andParseListInto: [:x | listContents := x].
	myServers size = 0 ifTrue: [self closeGroup.  ^ self].

	version := SystemVersion current version.
	versIndex := (listContents collect: [:pair | pair first]) indexOf: version.
	versIndex = 0 ifTrue:
		[self inform: 'There is no section in updates.list for your version'.
		self closeGroup.  ^ nil].	"abort"

	"A few affirmations..."
	versIndex < listContents size ifTrue:
		[(self confirm: 'This system, ', version ,
				' is not the latest version.\Make update for an older version?' withCRs)
			ifFalse: [self closeGroup.  ^ nil]].	"abort"
	(listContents at: versIndex) last isEmpty ifTrue:
		[(self confirm: 'Please confirm that you mean to issue the first update for ' ,
						version , '\(otherwise something is wrong).' withCRs)
			ifFalse: [self closeGroup.  ^ nil]].

	"We now determine next update number to be max of entire index"
	lastNum := listContents inject: 0 into:
		[:max :pair | pair last isEmpty
					ifTrue: [max]
					ifFalse: [max max: pair last last initialIntegerOrNil]].

	"Save old copy of updates.list on local disk"
	FileDirectory default deleteFileNamed: indexPrefix , 'updates.list.bk'.
	UpdateStreamDownloader default writeList: listContents toStream: (FileStream fileNamed: indexPrefix , 'updates.list.bk').

	"append name to updates with new sequence number"
	seq := (lastNum + 1) printString padded: #left to: 4 with: $0.
	"strip off any old seq number"
	stripped := localName copyFrom: (localName  findFirst: [:c | c isDigit not]) to: localName size.
	newName := seq , stripped.
	listContents at: versIndex put:
		{version. (listContents at: versIndex) last copyWith: newName}.

	"Write a new copy on all servers..."
	updateStrm := ReadStream on:
		(String streamContents: [:s | Utilities writeList: listContents toStream: s]).
	myServers do:
		[:aServer |
		fileStrm reset.	"reopen"
		aServer putFile: fileStrm named: newName retry: true.
		updateStrm reset.
		aServer putFile: updateStrm named: indexPrefix , 'updates.list' retry: true.
		Transcript show: 'Update succeeded on server ', aServer moniker; cr].
	self closeGroup.
		
	Transcript cr; show: 'Be sure to test your new update!!'; cr.
	"rename the file locally (may fail)"
	fileStrm directory rename: localName toBe: newName.
! !


!StandardToolSet class methodsFor: 'debugging - support' stamp: 'mt 9/16/2019 13:50'!
debugContext: aContext label: aString contents: contents
	"Open a debugger on the given process and context."
	^ self
		debug: Processor activeProcess
		context: aContext
		label: aString
		contents: contents
		fullView: false! !

!StandardToolSet class methodsFor: 'debugging - support' stamp: 'mt 9/16/2019 16:20'!
debugSyntaxError: aSyntaxErrorNotification
	
	^ Project current syntaxError: aSyntaxErrorNotification! !

!StandardToolSet class methodsFor: 'debugging' stamp: 'mt 9/16/2019 14:43'!
debugInterruptedProcess: aSuspendedProcess label: aString
	"Open a debugger on the given process, which is already suspended."

	^ Debugger
		openInterrupt: aString
		onProcess: aSuspendedProcess! !

!StandardToolSet class methodsFor: 'debugging' stamp: 'mt 9/16/2019 14:43'!
debugMethod: aCompiledMethod forReceiver: anObject inContext: aContext

	^ Debugger
		openOnMethod: aCompiledMethod forReceiver: anObject inContext: aContext! !

!StandardToolSet class methodsFor: 'debugging' stamp: 'mt 9/16/2019 14:43'!
debug: aProcess context: aContext label: aString contents: contents fullView: aBool
	"Open a debugger on the given process and context."

	^ Debugger
		openOn: aProcess context: aContext label: aString contents: contents fullView: aBool! !

!StandardToolSet class methodsFor: 'debugging' stamp: 'mt 9/16/2019 16:22'!
editSyntaxError: aSyntaxErrorNotification
	
	^ SyntaxError open: aSyntaxErrorNotification! !

!StandardToolSet class methodsFor: '*60Deprecated-debugging' stamp: 'mt 9/16/2019 11:33'!
interrupt: aProcess label: aString

	self deprecated: 'For a running process, use the Project interface. For a suspended process, use #debugInterruptedProcess: label: isntead.'.
	
	self debugInterruptedProcess: aProcess label: aString.! !


!SyntaxError methodsFor: 'other' stamp: 'nice 9/18/2013 21:24'!
contents: aString notifying: aController
	"Accept the code editions if syntax is correct.
	Then let the notification signalerContext proceed and restart compilation with these newSource."

	"In case of failure, return false so as to not accept the edits"
	notification reparse: aString notifying: aController ifFail: [^false].

	"else accept edits and proceed"
	aController hasUnacceptedEdits: false.
	self proceed! !

!SyntaxError methodsFor: 'toolbuilder' stamp: 'mt 9/16/2019 16:27'!
buildWith: builder

	| windowSpec listSpec textSpec |
	windowSpec := builder pluggableWindowSpec new
		model: self;
		label: 'Syntax Error';
		children: OrderedCollection new.

	listSpec := builder pluggableListSpec new.
	listSpec 
		model: self;
		list: #list; 
		getIndex: #listIndex; 
		setIndex: nil; 
		menu: #listMenu:;
		frame: (0@0 corner: 1@0.15).
	windowSpec children add: listSpec.

	textSpec := builder pluggableCodePaneSpec new.
	textSpec 
		model: self;
		getText: #contents; 
		setText: #contents:notifying:; 
		selection: #contentsSelection; 
		menu: #codePaneMenu:shifted:;
		frame: (0@0.15 corner: 1@1).
	windowSpec children add: textSpec.

	^ builder build: windowSpec! !

!SyntaxError methodsFor: 'accessing' stamp: 'mt 9/16/2019 16:30'!
contentsSelection

	^ notification ifNil: [1 to: 0] ifNotNil: [self errorMessageInterval]! !

!SyntaxError methodsFor: 'accessing' stamp: 'mt 9/16/2019 16:46'!
debugger

	^ debugger! !

!SyntaxError methodsFor: 'accessing' stamp: 'mt 9/16/2019 16:30'!
setNotification: aSyntaxErrorNotification

	| types printables badChar code |
	notification := aSyntaxErrorNotification.
	class := aSyntaxErrorNotification errorClass.
	
	debugger := Project current debuggerClass new.
	debugger context: aSyntaxErrorNotification signalerContext.
	
	code := aSyntaxErrorNotification errorCode.
	selector := class newParser parseSelector: code.
	types := Scanner classPool at: #TypeTable.	"dictionary"
	printables := '!!@#$%&*-_=+<>{}?/\,·£¢§¶ªºÚæÚ¯×¿«»`~`' asSet.
	badChar := code detect: [:aChar | (types at: aChar asciiValue ifAbsent: [#xLetter]) == #xBinary and: [
			(printables includes: aChar) not]] ifNone: [nil].
	contents := badChar 
		ifNil: [code]
		ifNotNil: ['<<<This string contains a character (ascii value ', 
			badChar asciiValue printString,
			') that is not normally used in code>>> ', code].
		
	self changed: #contentsSelection.! !

!SyntaxError methodsFor: 'initialize-release' stamp: 'mt 9/16/2019 15:54'!
initialExtent

	^ 380@220! !


!SyntaxError class methodsFor: 'instance creation' stamp: 'mt 9/16/2019 16:59'!
open: aSyntaxErrorNotification
	
	^ ToolBuilder default openDebugger: (self new setNotification: aSyntaxErrorNotification; yourself)! !


!ToolSet class methodsFor: '*60Deprecated-debugging' stamp: 'mt 9/16/2019 11:33'!
interrupt: aProcess label: aString

	self deprecated: 'For a running process, use the Project interface. For a suspended process, use #debugInterruptedProcess: label: isntead.'.
	
	self debugInterruptedProcess: aProcess label: aString.! !

!ToolSet class methodsFor: 'debugging' stamp: 'mt 9/16/2019 11:34'!
debugInterruptedProcess: aSuspendedProcess label: aString
	"Open a debugger on the given process, which is already suspended."
	self default ifNil:[
		(self confirm: 'Debugger request -- proceed?')
			ifFalse:[aSuspendedProcess terminate].
		^self].
	^self default debugInterruptedProcess: aSuspendedProcess label: aString! !

!ToolSet class methodsFor: 'debugging' stamp: 'mt 9/16/2019 14:32'!
debugMethod: aCompiledMethod forReceiver: anObject inContext: aContext

	self default ifNil:[
		self inform: 'Cannot debug method. It will just be executed.'.
		^ aCompiledMethod
			valueWithReceiver: anObject
			arguments: (aContext ifNil: [#()] ifNotNil: [{aContext}])].
	
	^self default debugMethod: aCompiledMethod forReceiver: anObject inContext: aContext
! !

!ToolSet class methodsFor: 'debugging' stamp: 'ar 9/27/2005 19:12'!
debugSyntaxError: anError
	"Handle a syntax error"
	self default ifNil:[^self debugError: anError]. "handle as usual error"
	^self default debugSyntaxError: anError! !

!ToolSet class methodsFor: 'debugging' stamp: 'mt 9/16/2019 16:35'!
editSyntaxError: aSyntaxErrorNotification
	"Handle a syntax error"
	self default ifNil:[
		self inform: 'Cannot fix syntax error interactively.'.
		Project uiManager edit: aSyntaxErrorNotification errorCode  label: 'Syntax Error'.
		^ self debugError: aSyntaxErrorNotification. "handle as usual error"].
	^self default editSyntaxError: aSyntaxErrorNotification! !


!WorldState methodsFor: 'update cycle' stamp: 'mt 9/16/2019 15:00'!
displayWorldSafely: aWorld
	"Update this world's display and keep track of errors during draw methods."

	| finished errors previousClasses |
	finished := false.
	errors := nil.
	
	[finished] whileFalse: [
		[aWorld displayWorld. finished := true] on: Error do: [:ex |
			"Handle a drawing error"
			| err rcvr errCtx errMorph |
			err := ex description.
			rcvr := ex receiver.

			errCtx := thisContext.
			[
				errCtx := errCtx sender.
				"Search the sender chain to find the morph causing the problem"
				[errCtx notNil and:[(errCtx receiver isMorph) not]] 
					whileTrue:[errCtx := errCtx sender].
				"If we're at the root of the context chain then we have a fatal drawing problem"
				errCtx ifNil:[^Project current handleFatalDrawingError: err].
				errMorph := errCtx receiver.
				"If the morph causing the problem has already the #drawError flag set,
				then search for the next morph above in the caller chain."
				errMorph hasProperty: #errorOnDraw
			] whileTrue.
			errMorph setProperty: #errorOnDraw toValue: true.

			"Catch all errors, one for each receiver class."
			errors ifNil: [errors := OrderedCollection new].
			previousClasses ifNil: [previousClasses := IdentitySet new].
			(previousClasses includes: rcvr class) ifFalse: [
				previousClasses add: rcvr class.
				errors add: (Process forContext: ex signalerContext copyStack priority: Processor activeProcess priority) -> err].
			aWorld fullRepaintNeeded.
		]].

	errors ifNotNil: [MorphicDebugger openDrawingErrors: errors].! !

MorphicUIManager removeSelector: #openDebugger:on:context:label:contents:fullView:!
MorphicUIManager removeSelector: #openSyntaxError:!
MorphicUIManager removeSelector: #resumeDebugger:process:!
MVCUIManager removeSelector: #openDebugger:on:context:label:contents:fullView:!
MVCUIManager removeSelector: #openSyntaxError:!
MVCUIManager removeSelector: #resumeDebugger:process:!
DummyUIManager removeSelector: #openDebugger:on:context:label:contents:fullView:!
DummyUIManager removeSelector: #resumeDebugger:process:!
UIManager removeSelector: #openDebugger:on:context:label:contents:fullView:!
UIManager removeSelector: #openSyntaxError:!
UIManager removeSelector: #resumeDebugger:process:!

!ToolSet class reorganize!
('accessing' askForDefault)
('browsing' browseChangeSetsWithClass:selector: browseClass: browseClass:category: browseHierarchy:selector: browseMessageCategory:inClass: browseMessageNames: browseMessageSet:name:autoSelect: browseVersionsOf:selector: browse:selector: openChangedMessageSet: openClassListBrowser:title:)
('*60Deprecated-debugging' interrupt:label:)
('debugging' debugContext:label:contents: debugError: debugInterruptedProcess:label: debugMethod:forReceiver:inContext: debugSyntaxError: debug:context:label:contents:fullView: editSyntaxError:)
('inspecting' basicInspect: explore: explore:label: inspect: inspect:label:)
('*60Deprecated-inspecting' inspectorClassOf:)
('menu' menuItems)
('completion' codeCompletionAround:textMorph:keyStroke:)
!

SyntaxError class removeSelector: #buildMVCViewOn:!
SyntaxError class removeSelector: #buildMorphicViewOn:!
SyntaxError class removeSelector: #morphicOpen:!
SyntaxError class removeSelector: #mvcOpen:!

!SyntaxError class reorganize!
('instance creation' open:)
!


!SyntaxError reorganize!
('menu' debug listMenu: proceed)
('message list' list listIndex)
('other' contents:notifying:)
('toolbuilder' buildWith:)
('text menu support' aboutToStyle: errorMessageInterval selectedClass selectedClassOrMetaClass selectedMessageName)
('accessing' contentsSelection debugger setNotification:)
('initialize-release' initialExtent release)
!


!StandardToolSet class reorganize!
('browsing' browseChangeSetsWithClass:selector: browseClass: browseClass:category: browseHierarchy:selector: browseMessageCategory:inClass: browseMessageNames: browseMessageSet:name:autoSelect: browseVersionsOf:selector: browse:selector: openChangedMessageSet: openClassListBrowser:title:)
('class initialization' initialize unload)
('debugging - support' debugContext:label:contents: debugError: debugSyntaxError:)
('debugging' debugInterruptedProcess:label: debugMethod:forReceiver:inContext: debug:context:label:contents:fullView: editSyntaxError:)
('inspecting' basicInspect: explore: explore:label: inspect: inspect:label:)
('*60Deprecated-inspecting' inspectorClassOf:)
('*60Deprecated-debugging' interrupt:label:)
('menu' menuItems openChangeSorter openClassBrowser openDualChangeSorter openFileList openMessageNames openPackagePaneBrowser openProcessBrowser openSelectorBrowser openWorkspace)
('completion' codeCompletionAround:textMorph:keyStroke:)
!

MorphicProject removeSelector: #debugMethod:forReceiver:inContext:!

!MorphicProject reorganize!
('display' invalidate noDisplayDuring: previewImageForm restore viewLocFor:)
('initialize' initMorphic initialize installPasteUpAsWorld: openProject: setWorldBackground:)
('testing' isMorphic)
('menu messages' assureNavigatorPresenceMatchesPreference makeThumbnail)
('utilities' addItem:toMenu:selection:color:thumbnail: composeDisplayTextIntoForm: createViewIfAppropriate do:withProgressInfoOn:label: findAFolderForProject:label: findProjectView: jumpToProject offerMenu:from:shifted: pointerMoved setAsBackground: showImage:named: textWindows)
('flaps support' assureFlapIntegrity cleanseDisabledGlobalFlapIDsList enableDisableGlobalFlap: flapsSuppressed: globalFlapEnabledString: globalFlapWithIDEnabledString: isFlapEnabled: isFlapIDEnabled: setFlaps suppressFlapsString toggleFlapsSuppressed)
('docking bars support' assureMainDockingBarPresenceMatchesPreference createOrUpdateMainDockingBar dockingBar dockingBar: removeMainDockingBar showWorldMainDockingBar showWorldMainDockingBar: showWorldMainDockingBarString toggleShowWorldMainDockingBar)
('file in/out' acceptProjectDetails: armsLengthCommand:withDescription: compressFilesIn:to:in: compressFilesIn:to:in:resources: exportSegmentInSexpWithChangeSet:fileName:directory:withoutInteraction: exportSegmentWithChangeSet:fileName:directory: exportSegmentWithChangeSet:fileName:directory:withoutInteraction: loadFromServer: noteManifestDetailsIn: storeSegment storeSegmentNoFile)
('enter' clearGlobalState enterAsActiveSubprojectWithin: finalEnterActions: finalExitActions: initializeMenus isIncompletelyLoaded resumeEventRecorder: scheduleProcessForEnter suspendProcessForDebug terminateProcessForLeave wakeUpTopWindow)
('squeaklet on server' enterIfThereOrFind: openBlankProjectNamed:)
('release' deletingProject: myPlayerClasses okToChange prepareForDelete)
('language' chooseNaturalLanguage updateLocaleDependents)
('*Etoys-stack' currentStack currentStack:)
('editors' bitEdit: bitEdit:at:scale: editCharacter:ofFont: formEdit: formViewClass openImage:name:saveResource:)
('futures' future:do:at:args: future:send:at:args:)
('protocols' currentVocabulary)
('active process' spawnNewProcess spawnNewProcessAndTerminateOld: spawnNewProcessIfThisIsUI: uiProcess uiProcess:)
('transcripter' displayTranscripter: initializeParagraphForTranscripter:)
('*46Deprecated' exportSegmentWithCatagories:classes:fileName:directory:)
('*51Deprecated' pauseEventRecorder pauseSoundPlayers triggerClosingScripts)
('subprojects' addProject: subProjects)
('accessing' color)
('scheduling & debugging' addDeferredUIMessage: debuggerClass interruptName: interruptName:preemptedProcess: syntaxError:)
('updating' applyUserInterfaceTheme canApplyUserInterfaceTheme)
('*Etoys-Worlds' setWorld:)
!

MVCProject removeSelector: #debugMethod:forReceiver:inContext:!

!MVCProject reorganize!
('display' invalidate restore viewLocFor:)
('initialize' initialize openProject:)
('utilities' addItem:toMenu:selection:color:thumbnail: composeDisplayTextIntoForm: do:withProgressInfoOn:label: findAFolderForProject:label: findProjectView: jumpToProject offerMenu:from:shifted: setAsBackground: showImage:named: subProjects textWindows)
('file in/out' armsLengthCommand:withDescription: exportSegmentWithCatagories:classes:fileName:directory: exportSegmentWithChangeSet:fileName:directory: storeSegment storeSegmentNoFile)
('enter' finalEnterActions: finalExitActions: scheduleProcessForEnter terminateProcessForLeave)
('project parameters' initializeProjectPreferences)
('editors' bitEdit: bitEdit:at:scale: editCharacter:ofFont: formEdit: formViewClass openImage:name:saveResource:)
('protocols' currentVocabulary)
('active process' spawnNewProcessIfThisIsUI: uiProcess)
('transcripter' displayTranscripter: initializeParagraphForTranscripter:)
('testing' isMVC)
('*51Deprecated' pauseSoundPlayers)
('accessing' color)
('scheduling & debugging' addDeferredUIMessage: debuggerClass interruptName: interruptName:preemptedProcess: syntaxError:)
('release' deletingProject: okToChange)
('sub-projects & hierarchy' addProject:)
!

Project removeSelector: #debugMethod:forReceiver:inContext:!

!Project reorganize!
('accessing' changeSet color displayDepth displayDepth: findProjectView: forgetExistingURL labelString lastDirectory: lastSavedAtSeconds name nameAdjustedForDepth nextProject previousProject projectChangeSet renameTo: setViewSize: storeNewPrimaryURL: thumbnail thumbnail: uiManager urlList viewSize world)
('active process' depth spawnNewProcessIfThisIsUI: uiProcess)
('displaying' displayDepthChanged displaySizeChanged displayZoom: handleFatalDrawingError: imageForm imageFormOfSize:depth: invalidate noDisplayDuring: previewImageForm restore restoreDisplay showZoom viewLocFor:)
('file in/out' armsLengthCommand:withDescription: assureIntegerVersion bumpVersion: couldBeSwappedOut currentVersionNumber decideAboutCreatingBlank: doArmsLengthCommand: downloadUrl ensureChangeSetNameUnique exportSegmentFileName:directory: exportSegmentFileName:directory:withoutInteraction: exportSegmentInSexpWithChangeSet:fileName:directory:withoutInteraction: exportSegmentWithCatagories:classes:fileName:directory: exportSegmentWithChangeSet:fileName:directory: findAFolderToLoadProject>From findAFolderToStoreProjectIn fromMyServerLoad: hasBadNameForStoring htmlPagePrototype loadFromServer loadFromServer: objectForDataStream: primaryServer primaryServerIfNil: projectExtension restoreReferences revert saveAs saveForRevert serverList squeakletDirectory storeAttributeKey:value:on: storeAttributesOn: storeDataOn: storeHtmlPageIn: storeManifestFileIn: storeOnServer storeOnServerAssumingNameValid storeOnServerInnards storeOnServerShowProgressOn:forgetURL: storeOnServerWithProgressInfo storeOnServerWithProgressInfoOn: storeSegment storeSegmentNoFile storeSomeSegment storeToMakeRoom tryToFindAServerWithMe url urlForLoading versionForFileName versionFrom: versionedFileName writeFileNamed:fromDirectory:toServer: writeStackText:in:registerIn:)
('flaps support' flapsSuppressed flapsSuppressed: showSharedFlaps)
('initialization' initialExtent initialProject initialize installNewDisplay:depth: openProject: setChangeSet: setServer windowActiveOnFirstClick windowReqNewLabel:)
('language' chooseNaturalLanguage localeChanged localeID naturalLanguage updateLocaleDependents)
('menu messages' assureNavigatorPresenceMatchesPreference doWeWantToRename exit fileOut installProjectPreferences makeThumbnail saveProjectPreferences toggleFullScreen validateProjectNameIfOK:)
('printing' addSubProjectNamesTo:indentation: printOn:)
('project parameters' initializeProjectParameters initializeProjectPreferences noteThatParameter:justChangedTo: parameterAt: parameterAt:ifAbsent: projectParameterAt: projectParameterAt:ifAbsent: projectParameterAt:ifAbsentPut: projectParameterAt:put: projectParameters projectPreferenceAt: projectPreferenceAt:ifAbsent: projectPreferenceFlagDictionary rawParameters removeParameter:)
('release' addDependent: canDiscardEdits delete deletingProject: forget okToChange prepareForDelete release removeChangeSetIfPossible windowIsClosing)
('resources' abortResourceLoading resourceDirectoryName resourceManager resourceManager: resourceUrl startResourceLoading storeResourceList:in:)
('SuperSwiki' tellAFriend tellAFriend:)
('*sound' beep)
('enter' enter enter: enter:revert:saveForRevert: finalEnterActions: finalExitActions: loadState saveState scheduleProcessForEnter terminateProcessForLeave wakeUpTopWindow)
('utilities' addItem:toMenu:selection:color:thumbnail: buildJumpToMenu: composeDisplayTextIntoForm: do:withProgressInfoOn:label: findAFolderForProject:label: jumpToProject jumpToSelection: offerMenu:from:shifted: pointerMoved setAsBackground: showImage:named: textWindows)
('squeaklet on server' enterIfThereOrFind: openBlankProjectNamed:)
('futures' future:do:at:args: future:send:at:args:)
('editors' bitEdit: bitEdit:at:scale: editCharacter:ofFont: formEdit: formViewClass openImage:name:saveResource:)
('protocols' currentVocabulary)
('transcripter' displayTranscripter: initializeParagraphForTranscripter:)
('*51Deprecated' finalEnterActions finalExitActions fullScreenOff fullScreenOn lastScreenModeSelected pauseEventRecorder pauseSoundPlayers resetDisplay triggerClosingScripts)
('sub-projects & hierarchy' addProject: beTopProject children isTopProject liftSubProjects parent setParent: subProjects withChildrenDo:)
('scheduling & debugging' addDeferredUIMessage: debuggerClass interruptName: interruptName:preemptedProcess: syntaxError:)
('enter - recovery' enterForEmergencyRecovery suspendProcessForDebug)
('testing' isCurrentProject isIncompletelyLoaded isMorphic)
('shrinking' removeAllOtherProjects)
('*ST80-Testing' isMVC)
('*Etoys-Squeakland-file in/out' defaultFolderForAutoSaving latestProjectVersionsFromFileEntries: storeOnServerWithNoInteraction storeOnServerWithNoInteractionInnards storeOnServerWithNoInteractionThenQuit storePngThumbnailIn: version: writeForExportInSexp:withSources:inDirectory:changeSet:)
('*60Deprecated-accessing' setThumbnail:)
('*Etoys-Squeakland-displaying' displayExtent)
('*Etoys-Squeakland-menu messages' displayProgressWithJump: displaySavingProgress)
('*Etoys-Squeakland-flaps support' helpGuideIfOpen)
('*Etoys-Squeakland-initialization' installVirtualDisplayIfNeededFor:)
('*Etoys-Squeakland-sugar' keepSugarProperties:monitor: sugarObjectId sugarObjectId: sugarProperties sugarProperties:)
('*Etoys-Squeakland-language' locales localesString toggleUseLocale updateLocaleDependentsGently updateLocaleDependentsWithPreviousSupplies:gently: useLocaleString)
('*Etoys-Squeakland-accessing' name:)
('*Etoys-Squeakland-release' okToChangeSilently)
!


!Process reorganize!
('accessing' calleeOf: copyStack effectiveProcess name name: offList priority priority: suspendedContext suspendingList)
('changing process state' resume run suspend terminate)
('changing suspended state' activateReturn:value: complete: completeStep: completeTo: install: popTo: popTo:value: restartTop restartTopWith: return:value: step step: stepToCallee stepToHome: stepToSendOrReturn)
('debugging' debug debug:title: debug:title:full: debug:title:full:contents: debugWithTitle:)
('objects from disk' objectForDataStream:)
('printing' browserPrintString browserPrintStringWith: longPrintOn: printOn:)
('signaling' pvtSignal:list: signalException:)
('private' evaluate:onBehalfOf: releaseCriticalSection: suspendedContext:)
('*KernelTests-Processes' suspendPrimitivelyOrFail)
('process specific' environmentAt: environmentAt:ifAbsent: environmentAt:ifAbsentPut: environmentAt:put: environmentKeyNotFound environmentRemoveKey: environmentRemoveKey:ifAbsent:)
('testing' isActiveProcess isBlocked isRunnable isSuspended isTerminated)
!

MorphicToolBuilder removeSelector: #openDebugger:!
MorphicToolBuilder removeSelector: #openDebugger:label:!

!MorphicDebugger class reorganize!
('opening' openDrawingErrors: openInterrupt:onProcess: openOn:context:label:contents:fullView: openOnMethod:forReceiver:inContext:)
!


!MorphicDebugger reorganize!
('accessing' errorWasInUIProcess errorWasInUIProcess:)
('initialize' initialize windowIsClosing)
('private' resumeProcess:)
!

MVCDebugger removeSelector: #mvcResumeProcess:!

!MVCDebugger reorganize!
('initialize' context: process:controller:context: windowIsClosing)
('private' resumeProcess:)
!


!DebuggerExtensionsTest reorganize!
('tests - canonical argument names' testBooleansGeneralise testByteStringsGeneralise testClassesGeneralise testCollectionsGeneralise testFloatsGeneralise testFractionsGeneralise testIntegersDontGeneralise testLargeNegativeIntegersGeneralise testLargePositiveIntegersGeneralise testOtherObjectsDontGeneralise testScaledDecimalsGeneralise testStringsDontGeneralise testWideStringsGeneralise)
!

Debugger class removeSelector: #morphicOpenOn:context:label:contents:fullView:!
Debugger class removeSelector: #mvcOpenOn:context:label:contents:fullView:!

!Debugger class reorganize!
('class initialization' initialize)
('instance creation' informExistingDebugger:label:)
('*System-opening' openInterrupt:onProcess: openOn:context:label:contents:fullView: openOnMethod:forReceiver:inContext:)
('error recursion' clearErrorRecursion setErrorRecursion)
('private' ifPreferredInterruptUIProcessIfBlocked:)
('preferences' errorReportServer errorReportServer: interruptUIProcessIfBlockedOnErrorInBackgroundProcess interruptUIProcessIfBlockedOnErrorInBackgroundProcess: wantsAnnotationPane wantsAnnotationPane:)
('*60Deprecated-opening' context: openContext:label:contents:)
!

Debugger removeSelector: #errorWasInUIProcess:!
Debugger removeSelector: #morphicResumeProcess:!
Debugger removeSelector: #mvcResumeProcess:!
Debugger removeSelector: #process:controller:context:!
CodeHolder subclass: #Debugger
	instanceVariableNames: 'interruptedProcess contextStack contextStackIndex contextStackList receiverInspector contextVariablesInspector externalInterrupt proceedValue selectingPC savedCursor isolationHead failedProject labelString message untilExpression'
	classVariableNames: 'ContextStackKeystrokes ErrorRecursion ErrorRecursionGuard ErrorReportServer InterruptUIProcessIfBlockedOnErrorInBackgroundProcess SavedExtent WantsAnnotationPane'
	poolDictionaries: ''
	category: 'Tools-Debugger'!

!Debugger reorganize!
('accessing' contents contents:notifying: contextStackTop contextVariablesInspector debuggerMap doNothing: interruptedContext interruptedProcess labelString labelString: proceedValue proceedValue: receiver receiverInspector receiverInspectorObject:context:)
('class list' selectedClass selectedClassOrMetaClass)
('code pane' aboutToStyle: codePaneSelectionInterval contentsSelection doItContext doItReceiver pc pcRange)
('code pane menu' debuggerCodePaneMenu: perform:orSendTo: runToSelection: runUntil)
('context stack menu' abandon abandon: askForCategoryIn:default: browseMessages browseSendersOfMessages browseVersions close: contextStackKey:from: contextStackMenu:shifted: copyBugReportToClipboard debugProceedMenu: doStep down fullStack handleLabelUpdatesIn:whenExecuting: implementMissingMethod:inClass: implementMissingMethod:inClass:inCategory: implementOverridingMethod:inClass:inCategory: mailOutBugReport mainContextStackMenu: messageListMenu:shifted: peelToFirst populateImplementInMenu: proceed proceed: restart returnValue selectPC send shiftedContextStackMenu: stepIntoBlock up where)
('context stack (message list)' contextStackIndex contextStackList expandStack fullyExpandStack messageHelpAt: messageIconAt: messageListIndex selectedMessage selectedMessageName toggleContextStackIndex:)
('dependents access' step updateInspectors wantsSteps)
('initialize' context: customButtonSpecs debugAt: initialExtent initialExtentForNotifier initialize openFullNoSuspendFrom: openFullNoSuspendLabel: openNotifierContents:label: preDebugButtonQuads process:context: release windowIsClosing)
('message category list' selectedMessageCategoryName)
('notifier menu' debug sendReport storeLog)
('toolbuilder' addCodeProvenanceButtonTo:using: buildCodePaneWith: buildControlButtonsWith: buildFullWith: buildNotifierWith:label:message: buildWith: classHierarchy contextStackFrame controlButtonsFrame optionalButtonsFrame preDebugButtonQuadFrame preDebugMessageString receiverClass textFrame wantsAnnotationPane wantsOptionalButtons)
('private' askForSuperclassOf:toImplement:ifCancel: askForSuperclassOf:upTo:toImplement:ifCancel: checkContextSelection contextStackIndex:oldContextWas: createImplementingMethod createMethod createOverridingMethod cutBackExecutionToSenderContext externalInterrupt: lowSpaceChoices newStack: pushStubMethodOnStack:inClass:inCategory: resetContext: resetContext:changeContents: resumeProcess: selectedContext)
('tally support' getSelectedText tally)
('self-updating' updateCodePaneIfNeeded)
('user interface' defaultWindowColor interruptedProcessIsActive)
('*Etoys-Squeakland-initialize' buttonRowForPreDebugWindow: preDebugNotifierContentsFrom:)
!

ControlManager removeSelector: #interruptName:!
ControlManager removeSelector: #interruptName:preemptedProcess:!

!ControlManager reorganize!
('accessing' activeController activeController: activeControllerNoTerminate:andProcess: activeControllerProcess controllerSatisfying: controllerWhoseModelSatisfies: controllersSatisfying: includes: noteNewTop scheduledControllers scheduledWindowControllers screenController windowOriginsInUse)
('displaying' backgroundForm: displayWorld restore restore: restore:below:without: restore:without: updateGray)
('initialize-release' initialize release)
('scheduling' activateController: activateTranscript findWindow findWindowSatisfying: inActiveControllerProcess promote: resetActiveController scheduleActive: scheduleActiveNoTerminate: scheduleOnBottom: schedulePassive: searchForActiveController spawnNewProcess unschedule: windowFromUser)
('private' emergencyCollapse nextActiveController scheduled:from: unCacheWindows)
!


!Object reorganize!
('accessing' at: at:modify: at:put: basicAt: basicAt:put: basicSize bindWithTemp: enclosedSetElement ifNil:ifNotNilDo: ifNotNilDo: ifNotNilDo:ifNil: in: presenter readFromString: size yourself)
('associating' ->)
('binding' bindingOf:)
('casing' caseOf: caseOf:otherwise:)
('class membership' class inheritsFromAnyIn: isKindOf: isKindOf:orOf: isMemberOf: respondsTo: xxxClass)
('comparing' closeTo: hash identityHashPrintString = literalEqual: ~=)
('converting' adaptToFloat:andCompare: adaptToFloat:andSend: adaptToFraction:andCompare: adaptToFraction:andSend: adaptToInteger:andCompare: adaptToInteger:andSend: adaptToScaledDecimal:andCompare: asOrderedCollection asSetElement asString asStringOrText as: changeClassTo: complexContents mustBeBoolean mustBeBooleanIn: printDirectlyToDisplay withoutListWrapper)
('copying' copy copyAddedStateFrom: copyFrom: copySameFrom: copyTwoLevel deepCopy initialDeepCopierSize postCopy shallowCopy veryDeepCopy veryDeepCopySibling veryDeepCopyUsing: veryDeepCopyWith: veryDeepFixupWith: veryDeepInner:)
('debugging' haltIf: needsWork)
('debugging-haltOnce' checkHaltCountExpired clearHaltOnce decrementAndCheckHaltCount decrementHaltCount doExpiredHaltCount doExpiredHaltCount: doExpiredInspectCount haltOnCount: haltOnce haltOnceEnabled haltOnce: halt:onCount: hasHaltCount inspectOnCount: inspectOnce inspectUntilCount: removeHaltCount setHaltCountTo: setHaltOnce toggleHaltOnce)
('dependents access' addDependent: breakDependents canDiscardEdits dependents evaluate:wheneverChangeIn: hasUnacceptedEdits myDependents myDependents: release removeDependent:)
('drag and drop' acceptDroppingMorph:event:inMorph: dragPassengerFor:inMorph: dragStartedFor:transferMorph: dragTransferTypeForMorph: wantsDroppedMorph:event:inMorph:)
('error handling' assert: assert:descriptionBlock: assert:description: backwardCompatibilityOnly: caseError deprecated deprecated: deprecated:block: doesNotUnderstand: dpsTrace: dpsTrace:levels: dpsTrace:levels:withContext: error error: halt halt: handles: notify: notify:at: primitiveFailed primitiveFailed: shouldBeImplemented shouldNotImplement subclassResponsibility traitConflict)
('evaluating' value valueWithArguments:)
('filter streaming' byteEncode: drawOnCanvas: elementSeparator encodePostscriptOn: flattenOnStream: fullDrawPostscriptOn: putOn: writeOnFilterStream:)
('flagging' isThisEverCalled isThisEverCalled: logEntry logExecution logExit)
('graph model' addModelYellowButtonMenuItemsTo:forMorph:hand: hasModelYellowButtonMenuItems)
('macpal' codeStrippedOut: contentsChanged flash instanceVariableValues isUniversalTiles objectRepresented refusesToAcceptCode scriptPerformer slotInfo)
('message handling' executeMethod: perform: perform:orSendTo: perform:with:with:with:with: perform:with:with:with:with:with: perform:withArguments: perform:withArguments:inSuperclass: perform:withEnoughArguments: perform:with: perform:with:with: perform:with:with:with: withArgs:executeMethod: with:executeMethod: with:with:executeMethod: with:with:with:executeMethod: with:with:with:with:executeMethod:)
('objects from disk' comeFullyUpOnReload: convertToCurrentVersion:refStream: fixUponLoad:seg: objectForDataStream: readDataFrom:size: saveOnFile saveOnFileNamed: storeDataOn:)
('printing' fullPrintString isLiteral longPrintOn: longPrintOn:limitedTo:indent: longPrintString longPrintStringLimitedTo: nominallyUnsent: printOn: printString printStringLimitedTo: printWithClosureAnalysisOn: reportableSize storeOn: storeString stringForReadout stringRepresentation)
('scripting' adaptedToWorld: defaultFloatPrecisionFor: evaluateUnloggedForSelf: methodInterfacesForCategory:inVocabulary:limitClass: methodInterfacesForInstanceVariablesCategoryIn: methodInterfacesForScriptsCategoryIn: selfWrittenAsIll selfWrittenAsIm selfWrittenAsMe selfWrittenAsMy selfWrittenAsThis)
('system primitives' asOop className creationStamp instVarAt: instVarAt:put: instVarNamed: instVarNamed:put: oopString primitiveChangeClassTo: rootStubInImageSegment: someObject)
('testing' beViewed belongsToUniClass costumes haltIfNil isArray isBehavior isBlock isBoolean isCharacter isClassReference isClosure isCodeReference isCollection isColor isColorForm isCompiledCode isCompiledMethod isComplex isContext isDictionary isFloat isForm isFraction isHeap isInteger isInterval isMessageSend isMethodContext isMethodProperties isMethodReference isMorph isMorphicEvent isMorphicModel isNumber isPlayer isPoint isPrimitiveCostume isPromise isRectangle isScriptEditorMorph isSketchMorph isStream isString isSymbol isSystemWindow isText isTextView isTrait isTransparent isVariableBinding isWebBrowser isWindowForModel: knownName name nameForViewer renameInternal: renameTo: shouldBePrintedAsLiteral shouldBePrintedAsLiteralVisiting: showDiffs stepAt:in: stepIn: stepTime stepTimeIn: vocabularyDemanded wantsDiffFeedback wantsSteps wantsStepsIn:)
('updating' changed changed: changed:with: handledListVerification noteSelectionIndex:for: okToChange okToClose updateListsAndCodeIn: update: update:with: windowIsClosing)
('user interface' addModelItemsToWindowMenu: addModelMenuItemsTo:forMorph:hand: asExplorerString defaultLabelForInspector launchPartVia: launchPartVia:label: launchTileToRefer modelSleep modelWakeUp modelWakeUpIn: mouseUpBalk: notYetImplemented windowActiveOnFirstClick windowReqNewLabel:)
('*monticello' isConflict)
('*services-base' requestor)
('*system-support' isPrimitiveError systemNavigation)
('*60Deprecated-Tools' exploreAndYourself notifyWithLabel:)
('*Tools-Explorer' explore exploreWithLabel:)
('*tools-browser' browseHierarchy)
('private' errorImproperStore errorNonIntegerIndex errorNotIndexable errorSubscriptBounds: setPinned: species storeAt:inTempFrame:)
('thumbnail' iconOrThumbnailOfSize:)
('*Morphic-Explorer' explorerContents hasContentsInExplorer)
('futures' future future: futureDo:at:args: futureSend:at:args:)
('*Etoys-viewer' assureUniClass browseOwnClassSubProtocol categoriesForViewer: categoriesForVocabulary:limitClass: chooseNewNameForReference defaultLimitClassForVocabulary: defaultNameStemForInstances elementTypeFor:vocabulary: externalName graphicForViewerTab hasUserDefinedSlots infoFor:inViewer: initialTypeForSlotNamed: isPlayerLike methodInterfacesInPresentationOrderFrom:forCategory: newScriptorAround: newTileMorphRepresentative offerViewerMenuFor:event: offerViewerMenuForEvt:morph: renameScript: tilePhrasesForCategory:inViewer: tilePhrasesForMethodInterfaces:inViewer: tilePhrasesForSelectorList:inViewer: tileToRefer uniqueInstanceVariableNameLike:excluding: uniqueNameForReference uniqueNameForReferenceFrom: uniqueNameForReferenceOrNil updateThresholdForGraphicInViewerTab usableMethodInterfacesIn:)
('*Protocols' currentVocabulary haveFullProtocolBrowsed haveFullProtocolBrowsedShowingSelector:)
('*Etoys-tiles' basicType)
('*Tools-MessageSets' browseAllCallsOn: browseAllImplementorsOf:)
('*Tools-multi-window support' canHaveUnacceptedEdits)
('*morphic' asDraggableMorph asMorph asStringMorph asTextMorph isPluggableListMorph openAsMorph)
('*MorphicExtras-Undo' capturedState commandHistory purgeAllCommands redoFromCapturedState: refineRedoTarget:selector:arguments:in: refineUndoTarget:selector:arguments:in: rememberCommand: rememberUndoableAction:named: undoFromCapturedState:)
('*MorphicExtras-PartsBin' descriptionForPartsBin)
('tracing' inboundPointers inboundPointersExcluding: outboundPointers outboundPointersDo:)
('*Tools-Debugger' canonicalArgumentName chasePointers explorePointers shouldFollowOutboundPointers)
('*System-Object Events-accessing' actionForEvent: actionForEvent:ifAbsent: actionMap actionSequenceForEvent: actionsDo: createActionMap hasActionForEvent: setActionSequence:forEvent: updateableActionMap)
('*System-Change Notification-events' actionsWithReceiver:forEvent: renameActionsWithReceiver:forEvent:toEvent:)
('*System-Change Notification-converting' asActionSequence asActionSequenceTrappingErrors)
('*System-Tools-breakpoint' break)
('*ToolBuilder-Kernel-error handling' confirm: confirm:orCancel:)
('*EToys-user interface' eToyStreamedRepresentationNotifying:)
('*ToolBuilder-Kernel-user interface' inform:)
('*System-Support-user interface' initialExtent)
('*System-Localization-locales' localeChanged localeChangedGently translatedNoop)
('*System-Object Events-accessing-removing' releaseActionMap removeAction:forEvent: removeActionsForEvent: removeActionsSatisfying: removeActionsSatisfying:forEvent: removeActionsWithReceiver: removeActionsWithReceiver:forEvent:)
('*System-Object Events-accessing-triggering' triggerEvent: triggerEvent:ifNotHandled: triggerEvent:with: triggerEvent:with:ifNotHandled: triggerEvent:withArguments: triggerEvent:withArguments:ifNotHandled:)
('*System-Object Events-accessing-registering' when:evaluate: when:send:to: when:send:to:with: when:send:to:withArguments:)
('*Tools-inspecting' basicInspect inspect inspectWithLabel: inspectorClass)
('*Traits' explicitRequirement requirement)
('*Graphics-KernelExtensions' fullScreenSize)
('*System-Finalization' actAsExecutor executor finalizationRegistry finalize hasMultipleExecutors retryWithGC:until: toFinalizeSend:to:with:)
('*collections' asLink compareSafely:)
('*Tools-Browsing' browse)
('*System-Recovery-error handling' primitiveError:)
('*SUnit-testing' isTestClass)
('*51Deprecated' defaultBackgroundColor dragAnimationFor:transferMorph:)
('*Morphic-Events-Filtering' filterEvent:for:)
('*System-Preferences' applyUserInterfaceTheme canApplyUserInterfaceTheme userInterfaceTheme)
('*Etoys-Squeakland-accessing' customizeExplorerContents)
('*Etoys-Squeakland-comparing' eToysEQ: eToysGE: eToysGT: eToysLE: eToysLT: eToysNE:)
('*Etoys-Squeakland-error handling' eToysError:)
('*Etoys-Squeakland-Etoys-viewer' hasUserDefinedScripts)
('*Etoys-Squeakland-translation support' inline:)
('*Etoys-Squeakland-testing' isReallyString)
('*Etoys-Squeakland-user interface' launchPartOffsetVia:label:)
('*Etoys-Squeakland-translating' literalStringsDo:)
('*Etoys-Squeakland-Tweak-Kedama' test:ifTrue:ifFalse: times:repeat:)
('*Tools' environment)
('*60Deprecated-copying' clone)
('pinning' isPinned pin unpin)
('*Morphic-Kernel' currentEvent currentHand currentWorld)
('*EToys-Scripting-accessing' addInstanceVarNamed:withValue: basicAddInstanceVarNamed:withValue:)
('literals' allLiteralsDo: hasLiteral: hasLiteralSuchThat:)
!

