Commits

Ryan Macnak committed 46ade58

Remove superclass declaration from IDE modules

Comments (0)

Files changed (11)

-Newspeak3
+Newspeak3
+'HopscotchIDE'
+class Debugging usingPlatform: platform ide: ide = (
+"Newspeak debugger module. Must be instantiated through ProcessFinalizer.
 
-'HopscotchIDE'
+Copyright (c) 2009 Peter von der Ahe
 
-
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+''Software''), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
 
-class Debugging usingPlatform: platform ide: ide = NewspeakObject (
-"Newspeak debugger module. Must be instantiated through ProcessFinalizer.
-
-Copyright (c) 2009 Peter von der Ahe
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-''Software''), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
-|
-	"Imports" 
-	Gradient = platform brazil plumbing Gradient.
-
-	TextEditorFragment = platform hopscotch fragments TextEditorFragment.
-	Subject = platform hopscotch core Subject.
-
-	CodeEditorFragment = ide tools CodeEditorFragment.
-	ExpandableMethodPresenter = ide browsing ExpandableMethodPresenter.
-	MethodSubject = ide browsing MethodSubject.
-	IDEWindow = ide tools IDEWindow.
-	NSMethodInheritanceSubject = ide browsingNS3 MethodInheritanceSubject.
-	OneLineDefinitionTemplate = ide tools OneLineDefinitionTemplate.
-	ProgrammingPresenter = ide tools ProgrammingPresenter.
-	ide = ide.
-
-	Color = platform blackMarket Graphics Color.
-	OrderedCollection = platform collections OrderedCollection.
-	SqueakDebugger = platform blackMarket Tools Debugger.
-	TextColor = platform blackMarket Collections TextColor.
-	TextEmphasis = platform blackMarket Collections TextEmphasis.
-	UnhandledError = platform blackMarket Exceptions UnhandledError.
-
-	"Slots"
-	goldenRatio = (1 + 5 sqrt) / 2.
-	registry <ProcessFinalizer>
-	thread
-	activation
-	windowTitle
-|
-)
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
 
-(
+THE SOFTWARE IS PROVIDED ''AS IS'', WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."|
+	"Imports" 
+	Gradient = platform brazil plumbing Gradient.
 
-
+	TextEditorFragment = platform hopscotch fragments TextEditorFragment.
+	Subject = platform hopscotch core Subject.
 
-class ActivationSubject onModel: mirrorOnActivation <ActivationMirror> = MethodSubject onModel: mirrorOnActivation (
-	| methodMirror_slot |
-	)
+	CodeEditorFragment = ide tools CodeEditorFragment.
+	ExpandableMethodPresenter = ide browsing ExpandableMethodPresenter.
+	MethodSubject = ide browsing MethodSubject.
+	IDEWindow = ide tools IDEWindow.
+	NSMethodInheritanceSubject = ide browsingNS3 MethodInheritanceSubject.
+	OneLineDefinitionTemplate = ide tools OneLineDefinitionTemplate.
+	ProgrammingPresenter = ide tools ProgrammingPresenter.
+	ide = ide.
 
-('as yet unclassified'
+	Color = platform blackMarket Graphics Color.
+	OrderedCollection = platform collections OrderedCollection.
+	SqueakDebugger = platform blackMarket Tools Debugger.
+	TextColor = platform blackMarket Collections TextColor.
+	TextEmphasis = platform blackMarket Collections TextEmphasis.
+	UnhandledError = platform blackMarket Exceptions UnhandledError.
 
-= other <Object> ^<Boolean> = (
+	"Slots"
+	goldenRatio = (1 + 5 sqrt) / 2.
+	registry <ProcessFinalizer>
+	thread
+	activation
+	windowTitle
+|)
+(
+class ActivationPresenter onSubject: subj <ActivationSubject> = ExpandableMethodPresenter onSubject: subj (|
+	localVariables
+	okToRestartBlock ::= false.
+|)
+('as yet unclassified'
+buildActions = (
+	| object |
+	^column: {
+		row: {
+			button: 'over' action: [respondToStepOver].
+			smallBlank.
+			button: 'into' action: [respondToStepInto].
+			smallBlank.
+			button: 'into block' action: [respondToStepIntoBlock].
+			filler.
+			button: '^self' action: [respondtoReturnSelf].
+			smallBlank.
+			button: '^nil' action: [respondToReturnNil].
+			holder: [buildReturnInterestingValue].
+		}
+	}
+)
+buildLocalVariables = (
+	localVariables:: (ActivationStateSubject onModel: subject model) presenter.
+	^localVariables
+)
+buildMethodEditor = (
+	| methodEditor |
+	methodEditor:: super methodDetails.
+	methodEditor colorizerBlock:
+		[:text |
+		subject colorizeMethodSource: text in: methodEditor editor].
+	^methodEditor
+)
+buildReturnInterestingValue = (
+	subject lastInterestingValueOnStack ifNotNil:
+		[:it |
+		^row: {
+			smallBlank.
+			button: '^', (it reflecteePrintStringLimitedTo: 10) action: [respondToReturnValue: it].
+		}].
+	^nothing
+)
+clearErrors = (
+	editor ifNotNil: [:it | it removeMessages]
+)
+methodActionsMenu = (
+	^menuWithLabelsAndActions: {
+		'Versions' -> [respondToVersions].
+		subject isBlockActivation
+			ifTrue: ['Restart block' -> [respondToRestart]]
+			ifFalse: ['Restart method' -> [respondToRestart]].
+		'Unwind Recursion' -> [respondToUnwindRecursion].
+		'Inspect Context' -> [respondToInspectContext].
+		'Inspect Presenter' -> [respondToInspectPresenter].
+	},(
+		subject isMessageNotUnderstood
+			ifTrue: [{'Create missing method ', subject notUnderstoodMessage printString -> [respondToCreateMissing]}]
+			ifFalse: [{}]
+	)
+)
+methodDetails = (
+	^column: {
+		(row: {
+			(column: {
+				minorHeadingBlock: buildActions.
+				buildMethodEditor.
+			}) width: 0 elasticity: goldenRatio.
+			smallBlank.
+			buildLocalVariables width: 0 elasticity: 1.
+		}) color: self methodHeadingColor.
+	}
+)
+methodHeading = (
+	| heading |
+	heading:: super methodHeading.
+	subject implementingClass == subject receiverClass
+		ifTrue: [^heading].
+	headingAfterLeftHolder content: (
+		row: {
+			largeBlank.
+			(link: 'receiver class' action: [respondToBrowseReceiverClass]) tinyFont.
+		}
+	).
+	^heading
+)
+recategorizeMethodIn: p <Presenter> under: newCategoryName <String> ifSuccess: successResponse <Block> ifFailed: failureResponse <Block> = (
+	| newName |
+	newName:: newCategoryName withBlanksTrimmed.
+	newName isEmpty ifTrue: [^failureResponse value].
+	subject
+		changeCategoryTo: newName asSymbol
+		ifSuccess: successResponse
+		ifFailure: failureResponse
+)
+refresh = (
+	super refresh.
+	editor ifNotNil: [:it | it editor maybeColorize].
+	localVariables ifNotNil: [:it | it refresh].
+)
+respondToBrowseReceiverClass = (
+	browseClass: subject receiverClass
+)
+respondToCreateMissing = (
+	browseClass: subject receiverClass.
+	sendUp deliveryOptional navigatorDo:
+		[:navigator |
+		navigator currentPresenter sendDown
+			addMethodIn: subject receiverClass
+			proposedSource: subject proposedMissingMessageSource asString]
+)
+respondToInspectContext = (
+	inspect: subject model context_slot
+)
+respondToRestart = (
+	clearErrors.
+	subject restartIfFail: [:msg | editor showMessage: msg].
+	sendUp deliveryOptional refreshActivations
+)
+respondToReturn: textEditor <TextEditorFragment> = (
+	clearErrors.
+	subject
+		returnWith: textEditor editedText asString
+		ifFail: [:msg | editor showMessage: msg].
+	sendUp deliveryOptional refreshActivations
+)
+respondToReturnNil = (
+	subject returnNil.
+	sendUp deliveryOptional refreshActivations
+)
+respondToReturnValue: objectMirror <ObjectMirror> = (
+	subject return: objectMirror.
+	sendUp deliveryOptional refreshActivations
+)
+respondToStepInto = (
+	clearErrors.
+	subject stepIntoIfFail: [:msg | editor showMessage: msg].
+	sendUp deliveryOptional refreshActivations
+)
+respondToStepIntoBlock = (
+	clearErrors.
+	subject stepIntoBlockIfFail: [:msg | editor showMessage: msg].
+	sendUp deliveryOptional refreshActivations
+)
+respondToStepOver = (
+	clearErrors.
+	subject stepOverIfFail: [:msg | editor showMessage: msg].
+	sendUp deliveryOptional refreshActivations
+)
+respondToUnwindRecursion = (
+	clearErrors.
+	subject unwindRecursionIfFail: [:msg | editor showMessage: msg].
+	sendUp deliveryOptional refreshActivations
+)
+respondtoReturnSelf = (
+	subject return: subject receiverMirror.
+	sendUp deliveryOptional refreshActivations
+)
+showClassLink = (
+	^true
+)
+showClassName = (
+	^true
+))
+class ActivationStatePresenter onSubject: subj <ActivationStateSubject> = ProgrammingPresenter onSubject: subj (|
+	interactionEditor
+|)
+('as yet unclassified'
+acceptNewValue: template <DefinitionTemplate> for: variableName = (
+	subject
+		setLocalVariable: variableName
+		to: template text asString
+		ifFail: [:msg | template editor showMessage: msg].
+	sendUp deliveryOptional refreshActivations
+)
+additionalResultFragment: fragmentConsumer <[Fragment]> for: result <[ObjectMirror]> = (
+	fragmentConsumer
+		value: (link: 'return it' action: [respondToReturn: result]) tinyFont
+)
+buildExpressionStack = (
+	^nothing
+)
+buildExpressionStackOn: s <WriteStream[Presenter]> = (
+	s nextPut: smallBlank.
+	s nextPut:
+		(heading: (label: 'Expression Stack' asText allBold)
+		detailsExpanded:
+			[list: (subject stackIndicesWithValuesCollect:
+				[:i :mirror |
+				buildLocalVariable: i asString value: mirror])])
+)
+buildHeadingForLocalVariable: variableName value: object = (
+	^row: {
+		label: variableName asText allBold.
+		smallBlank.
+		link: (object reflecteePrintStringLimitedTo: 39) action:
+			[inspectObjectMirror: object].
+	}
+)
+buildInteraction = (
+	^inspection EvaluatorPresenter onSubject: subject
+)
+buildLocalVariable: variableName value: object = (
+	
+	^collapsed: [buildHeadingForLocalVariable: variableName value: object]
+	expanded:
+		[| template |
+		template:: OneLineDefinitionTemplate new
+			initialText: 'new value for ', variableName;
+			acceptResponse: [:t | acceptNewValue: t for: variableName];
+			cancelResponse: [:t | t editor defaultCancelResponse];
+			ensureSubstance.
+		template editor defaultCancelResponse.
+		column: {
+			template.
+			(objectSubjectForMirror: object) presenter selfCaption: variableName.
+		}]
+)
+buildSelf = (
+	^collapsed: [buildHeadingForLocalVariable: 'self' value: subject receiverMirror]
+		expanded: [(objectSubjectForMirror: subject receiverMirror) presenter]
+)
+definition = (
+	^list:
+		[Array streamContents:
+			[:s |
+			"s nextPut: ((padded: (buildInteraction color: self methodHeadingColor) with: {1. 1. 1. 1}) color: (Color gray: 0.75))."
+			s nextPut: buildInteraction.
+			s nextPut: buildSelf.
+			subject localNamesWithValuesDo:
+				[:localName :mirror |
+				s nextPut: (buildLocalVariable: localName value: mirror)].
+			buildExpressionStackOn: s]].
+)
+respondToEvaluate = (
+	
+)
+respondToReturn: mirror <ObjectMirror> = (
+	subject return: mirror.
+	sendUp deliveryOptional; refreshActivations
+))
+class ActivationStateSubject onModel: mirror <ActivationMirror> = Subject onModel: mirror ()
+('as yet unclassified'
+activationMirror = (
+	^model
+)
+createPresenter = (
+	^ActivationStatePresenter onSubject: self
+)
+evaluate: expression ifCompilerError: onCompilerError <[String]> ifError: onError <[NewspeakDebugging ThreadSubject, Exception]> ^<ObjectMirror> = (
+	| result compilerError |
+	compilerError:: {nil}.
+	result:: registry
+		do: [activationMirror evaluate: expression ifFail: [:msg | compilerError at: 1 put: msg]]
+		name: 'Evaluating ', expression
+		ifError:
+			[:exception :process |
+			onError value: (registry subjectFor: exception in: process) value: exception].
+	compilerError first ifNotNil:
+		[:message |
+		^onCompilerError valueWithPossibleArgument: message].
+	^result
+)
+localNamesWithValuesCollect: action <[Integer, ObjectMirror, ^T]> ^<SequenceableCollection[T]>= (
+	^Array streamContents:
+		[:s |
+		activationMirror localNamesWithValuesDo:
+			[:i :mirror | s nextPut: (action value: i value: mirror)]]
+)
+localNamesWithValuesDo: action <[String, ObjectMirror]> = (
+	activationMirror localNamesWithValuesDo: action
+)
+receiver = (
+	^activationMirror receiver
+)
+receiverMirror = (
+	^activationMirror receiverMirror
+)
+return: objectMirror = (
+	activation:: thread return: objectMirror from: activationMirror
+)
+setLocalVariable: variableName <String> to: exprString <String> ifFail: onFail <[String]> = (
+	activationMirror setLocalVariable: variableName to: exprString ifFail: onFail
+)
+stackIndicesWithValuesCollect: action <[Integer, ObjectMirror, ^T]> ^<SequenceableCollection[T]>= (
+	^Array streamContents:
+		[:s |
+		activationMirror stackIndicesWithValuesDo:
+			[:i :mirror | s nextPut: (action value: i value: mirror)]]
+)
+stackIndicesWithValuesDo: action <[Integer, ObjectMirror]> = (
+	activationMirror stackIndicesWithValuesDo: action
+)
+title = (
+	^'Expression Stack'
+))
+class ActivationSubject onModel: mirrorOnActivation <ActivationMirror> = MethodSubject onModel: mirrorOnActivation (| methodMirror_slot |)
+('as yet unclassified'
+= other <Object> ^<Boolean> = (
+	^self class = other class and: [model = other model]
+)
+activationMirror ^  <ActivationMirror> = (
+	^model
+)
+allMethodCategories ^<Collection[Symbol]> = (
+	"Answer a collection of all category names used in the implementor class, plus some common names."
+	
+	| names |
+	names:: super allMethodCategories.
+	names addAll: methodMirror enclosingClassStencil methodCategories.
+	^names
+)
+asMethodInheritanceSubject = (
+	^NSMethodInheritanceSubject onModel: methodMirror
+)
+changeCategoryTo: newName ifSuccess: successBlock ifFailure: failureBlock = (
+	methodMirror changeCategory: newName asSymbol.
+	successBlock value
+)
+classAndSelectorString = (
+	^model printString
+)
+colorizeMethodSource: sourceText = (
+	
+	methodMirror reflectee methodClass language isNewspeakLanguage3 
+		ifFalse:[^super colorizeMethodSource: sourceText].
 
-
+	^ide browsingNS3 NS3Colorizer new 
+		parseText: sourceText asString
+		fromClass: methodMirror definingMixin reflectee definingClass
+		usingSelector: #methodDecl
+)
+colorizeMethodSource: sourceText in: editor = (
+	| range |
+	range:: model pcRange.
+	sourceText asString = source asString ifTrue:
+		[editor selectFrom: range first to: range last.
+		^highlight: (colorizeMethodSource: sourceText) range: range].
+	^colorizeMethodSource: sourceText
+)
+compileNewSource: newSource <String> ifSuccess: onSuccess ifNewMethod: onNewMethod ifFailure: onFail = (
+	| method failed |
+	model homeMethod isSynthetic
+		ifTrue: [^onFail valueWithPossibleArgument: 'Cannot change synthetic method.'].
+	method:: activationMirror compile: newSource ifFail:
+		[:msg | ^onFail valueWithPossibleArgument: msg].
+	method simpleName = selector
+		ifFalse: [^onNewMethod valueWithPossibleArgument: method].
+	failed:: nil.
+	activation:: thread install: method restart: model homeInThread ifFail:
+		[:message | failed:: message].
+	failed ifNotNil: [:it | ^onFail valueWithPossibleArgument: it].
+	onSuccess value
+)
+createPresenter = (
+	^ActivationPresenter onSubject: self
+)
+hasLegacyMirror = (
+	^methodMirror enclosingClassStencil isLegacyMirror
+)
+hash ^<SmallInteger> = (
+	^self class hash bitXor: model hash
+)
+implementingClass = (
+	^model definingClass
+)
+isAnOverride = (
+	superclass ifNotNil: [:it | ^it canUnderstand: selector].
+	^false
+)
+isBlockActivation = (
+	^model isBlockMirror
+)
+isMessageNotUnderstood = (
+	^model isMessageNotUnderstood
+)
+isOverridden = (
+	^false
+)
+isPrivate = (
+	^methodMirror isPrivate
+)
+isValid = (
+	^true
+)
+lastInterestingValueOnStack ^<ObjectMirror | nil> = (
+	| mirror |
+	model stackIndicesWithValuesDo:
+		"Prefer topmost value which comes first"
+		[:ignored :current |
+		current reflecteeIsNil ifFalse: [^current]].
+	model localNamesWithValuesDo:
+		"Prefer last argument which comes last"
+		[:ignored :current |
+		current reflecteeIsNil ifFalse: [mirror:: current]].
+	^mirror
+)
+localNames = (
+	^model localNames
+)
+messages = (
+	^(model homeMethod ifNil: [^{}]) messages
+)
+methodCategory = (
+	^methodMirror category
+)
+methodMirror = (
+	^model methodMirror
+)
+notUnderstoodMessage = (
+	^model notUnderstoodMessage
+)
+proposedMissingMessageSource = (
+	^model proposedMissingMessageSource
+)
+receiver = (
+	^model receiver
+)
+receiverClass = (
+	^model receiverClass
+)
+receiverMirror = (
+	^model receiverMirror
+)
+restartIfFail: onFail <[String]> = (
+	activation:: thread restart: model
+)
+return: objectMirror = (
+	activation:: thread return: objectMirror from: model
+)
+returnNil = (
+	return: activationMirror nilMirror
+)
+returnWith: expression ifFail: onFail = (
+	return:: activationMirror evaluate: expression ifFail: [:msg | ^onFail value: msg]
+)
+selector = (
+	^model selector
+)
+source = (
+	^[model source] ifError: [:desc | desc]
+)
+stepIntoBlockIfFail: onFail = (
+	activation:: thread stepIntoBlock: model.
+)
+stepIntoIfFail: onFail = (
+	activation:: thread stepInto: model.
+)
+stepOverIfFail: onFail = (
+	activation:: thread stepOver: model.
+)
+superclass = (
+	"^methodMirror enclosingClassStencil guessSuperclass"
+	#BOGUS yourself.
+	^Object
+)
+unwindRecursionIfFail: onFail <[String]> = (
+	activation:: thread unwindRecursion: model.
+)
+variableBindingKeys = (
+	^Array streamContents:
+		[:s |
+		(model homeMethod ifNil:[^{}]) literalsDo:
+			[:lit |
+			(lit isVariableBinding and: [lit key notNil])
+				ifTrue: [s nextPut: lit key]]]
+))
+class ThreadPresenter onSubject: subj <ThreadSubject> = ProgrammingPresenter onSubject: subj (|
+	protected activations
+	protected definitionHolder
+|)
+('as yet unclassified'
+buildActivationsHeader = (
+	^majorHeadingBlock: (
+		row: {
+			label: 'Call stack' asText allBold.
+			filler.
+			expandButtonWithAction: [respondToExpandAll].
+			blank: 3.
+			collapseButtonWithAction: [respondToCollapseAll].
+		}
+	)
+)
+buildErrorReport = (
+	| toggle |
+	toggle:: heading: ((link: 'Error Report' action: [toggle userToggle]) color: Color black) details:
+		[TextEditorFragment new text: subject errorReport].
+	^toggle
+)
+buildMainActions = (
+	^padded: (row: {
+		filler.
+		button: 'Continue' action: [respondToResume].
+		largeBlank.
+		button: 'Terminate' action: [respondToTerminate].
+		filler.
+	}) with: {20. 20. 20. 20}
+)
+buildMainContent = (
+	^column: {
+		(padded: buildMainHeader with: {3. 3. 3. 3}) color: mainHeadingColor.
+		smallBlank.
+		buildErrorReport.
+		smallBlank.
+		buildActivationsHeader.
+		smallBlank.
+		activations.
+	}
+)
+buildMainHeader = (
+	^column: {
+		buildSummaryRow.
+		buildMainActions.
+	}
+)
+buildSummaryRow = (
+	^row: {
+		(label: subject summary) color: mainHeadingTextColor.
+		filler.
+		dropDownMenu: [secondaryActionsMenu].
+	}
+)
+chunkSize = (
+	^60
+)
+compileMethod: newSource <String>
+inPresenter: p <ActivationPresenter>
+ifCompiledAsSame: onCompiledAsSame <[]>
+ifCompiledAsNew: onCompiledAsNew <[]>
+ifFailed: onFail <[String]> = (
+	| edited home |
+	edited:: p subject activationMirror.
+	home:: edited homeInThread.
+	home ifNil: [^onFail value: 'Block''s method not on stack.'].
+	(edited = home or: [p okToRestartBlock]) ifFalse:
+		[p okToRestartBlock: true.
+		^onFail value: 'Need to revert to block''s method. Click Save again to revert.'].
+	p subject
+		compileNewSource: newSource
+		ifSuccess:
+			[refreshActivations.
+			onCompiledAsSame value]
+		ifNewMethod: onCompiledAsNew
+		ifFailure:
+			[:message |
+			refreshActivations.
+			onFail valueWithPossibleArgument: message].
+)
+definition = (
+	isAlive ifFalse: [^nothing].
+	activations:: list.
+	definitionHolder:: holder: [buildMainContent].
+	populateActivations.
+	^definitionHolder
+)
+expandFirst = (
+	activations presenters first expand
+)
+populateActivations = (
+	refreshWhenDone:
+		[ | presenters |
+		presenters:: OrderedCollection new.
+		subject activationsDo:
+			[:each |
+			presenters size > chunkSize ifTrue:
+				[schedulePresentation: presenters.
+				presenters:: OrderedCollection new].
+			presenters add: (ActivationSubject onModel: each) presenter].
+		schedulePresentation: presenters.
+		nil].
+)
+refreshActivations = (
+	| oldTop oldSender i <Integer> |
+	oldTop:: activations presenters first subject model.
+	oldSender:: (activations presenters at: 2) subject model.
 
-activationMirror ^  <ActivationMirror> = (
+	"Same activation"
+	oldTop == activation ifTrue:
+		[^majorUpdate: [refreshAll]].
 
-
+	"Returned to sender"
+	oldSender == activation ifTrue:
+		[^majorUpdate:
+			[activations presenters: (activations presenters copyWithout: activations presenters first).
+			refreshAll.
+			expandFirst]].
 
-allMethodCategories ^<Collection[Symbol]> = (
+	"Called other method"
+	(oldTop isSenderOf: activation) ifTrue:
+		[^majorUpdate:
+			[activations addFirst: (ActivationSubject onModel: activation) presenter.
+			refreshAll.
+			expandFirst]].
 
-
+	"More than one new activation on stack"
+	(activation hasActivation: oldTop) ifTrue:
+		[ | newPresenters |
+		newPresenters:: Array streamContents:
+			[:s | | current |
+			current:: activation.
+				[s nextPut: (ActivationSubject onModel: current) presenter.
+				oldTop isSenderOf: current] whileFalse:
+					[current:: current sender]].
+		^majorUpdate:
+			[refreshAll.
+			activations presenters: newPresenters, activations presenters.
+			expandFirst]].
 
-asMethodInheritanceSubject = (
+      i:: 0.
+	"See if activation was further up on the stack"
+	activations presenters do:
+		[:each  |
+		i:: i + 1.
+		each subject model == activation ifTrue:
+			[^majorUpdate:
+				[activations presenters: (activations presenters copyFrom: i to: activations presenters size).
+				expandFirst.
+				refreshAll]]].
 
-
-
-changeCategoryTo: newName ifSuccess: successBlock ifFailure: failureBlock = (
-
-
-
-classAndSelectorString = (
-
-
-
-colorizeMethodSource: sourceText = (
-
-
-
-colorizeMethodSource: sourceText in: editor = (
-
-
-
-compileNewSource: newSource <String> ifSuccess: onSuccess ifNewMethod: onNewMethod ifFailure: onFail = (
-
-
-
-createPresenter = (
-
-
-
-hasLegacyMirror = (
-
-
-
-hash ^<SmallInteger> = (
-
-
-
-implementingClass = (
-
-
-
-isAnOverride = (
-
-
-
-isBlockActivation = (
-
-
-
-isMessageNotUnderstood = (
-
-
-
-isOverridden = (
-
-
-
-isPrivate = (
-
-
-
-isValid = (
-
-
-
-lastInterestingValueOnStack ^<ObjectMirror | nil> = (
-
-
-
-localNames = (
-
-
-
-messages = (
-
-
-
-methodCategory = (
-
-
-
-methodMirror = (
-
-
-
-notUnderstoodMessage = (
-
-
-
-proposedMissingMessageSource = (
-
-
-
-receiver = (
-
-
-
-receiverClass = (
-
-
-
-receiverMirror = (
-
-
-
-restartIfFail: onFail <[String]> = (
-
-
-
-return: objectMirror = (
-
-
-
-returnNil = (
-
-
-
-returnWith: expression ifFail: onFail = (
-
-
-
-selector = (
-
-
-
-source = (
-
-
-
-stepIntoBlockIfFail: onFail = (
-
-
-
-stepIntoIfFail: onFail = (
-
-
-
-stepOverIfFail: onFail = (
-
-
-
-superclass = (
-
-
-
-unwindRecursionIfFail: onFail <[String]> = (
-
-
-
-variableBindingKeys = (
-
-
-
-)
-
-
-
-class ActivationStatePresenter onSubject: subj <ActivationStateSubject> = ProgrammingPresenter onSubject: subj (
-|
-	interactionEditor
-|
-)
-
-('as yet unclassified'
-
-acceptNewValue: template <DefinitionTemplate> for: variableName = (
-
-
-
-additionalResultFragment: fragmentConsumer <[Fragment]> for: result <[ObjectMirror]> = (
-
-
-
-buildExpressionStack = (
-
-
-
-buildExpressionStackOn: s <WriteStream[Presenter]> = (
-
-
-
-buildHeadingForLocalVariable: variableName value: object = (
-
-
-
-buildInteraction = (
-
-
-
-buildLocalVariable: variableName value: object = (
-
-
-
-buildSelf = (
-
-
-
-definition = (
-
-
-
-respondToEvaluate = (
-
-
-
-respondToReturn: mirror <ObjectMirror> = (
-
-
-
-)
-
-
-
-class ActivationStateSubject onModel: mirror <ActivationMirror> = Subject onModel: mirror ()
-
-('as yet unclassified'
-
-activationMirror = (
-
-
-
-createPresenter = (
-
-
-
-evaluate: expression ifCompilerError: onCompilerError <[String]> ifError: onError <[NewspeakDebugging ThreadSubject, Exception]> ^<ObjectMirror> = (
-
-
-
-localNamesWithValuesCollect: action <[Integer, ObjectMirror, ^T]> ^<SequenceableCollection[T]>= (
-
-
-
-localNamesWithValuesDo: action <[String, ObjectMirror]> = (
-
-
-
-receiver = (
-
-
-
-receiverMirror = (
-
-
-
-return: objectMirror = (
-
-
-
-setLocalVariable: variableName <String> to: exprString <String> ifFail: onFail <[String]> = (
-
-
-
-stackIndicesWithValuesCollect: action <[Integer, ObjectMirror, ^T]> ^<SequenceableCollection[T]>= (
-
-
-
-stackIndicesWithValuesDo: action <[Integer, ObjectMirror]> = (
-
-
-
-title = (
-
-
-
-)
-
-
-
-class ActivationPresenter onSubject: subj <ActivationSubject> = ExpandableMethodPresenter onSubject: subj (
-|
-	localVariables
-	okToRestartBlock ::= false.
-|
-)
-
-('as yet unclassified'
-
-buildActions = (
-
-
-
-buildLocalVariables = (
-
-
-
-buildMethodEditor = (
-
-
-
-buildReturnInterestingValue = (
-
-
-
-clearErrors = (
-
-
-
-methodActionsMenu = (
-
-
-
-methodDetails = (
-
-
-
-methodHeading = (
-
-
-
-recategorizeMethodIn: p <Presenter> under: newCategoryName <String> ifSuccess: successResponse <Block> ifFailed: failureResponse <Block> = (
-
-
-
-refresh = (
-
-
-
-respondToBrowseReceiverClass = (
-
-
-
-respondToCreateMissing = (
-
-
-
-respondToInspectContext = (
-
-
-
-respondToRestart = (
-
-
-
-respondToReturn: textEditor <TextEditorFragment> = (
-
-
-
-respondToReturnNil = (
-
-
-
-respondToReturnValue: objectMirror <ObjectMirror> = (
-
-
-
-respondToStepInto = (
-
-
-
-respondToStepIntoBlock = (
-
-
-
-respondToStepOver = (
-
-
-
-respondToUnwindRecursion = (
-
-
-
-respondtoReturnSelf = (
-
-
-
-showClassLink = (
-
-
-
-showClassName = (
-
-
-
-)
-
-
-
-class ThreadSubject onModel: t <ThreadMirror> = Subject onModel: t ()
-
-('as yet unclassified'
-
-activationsDo: action = (
-
-
-
-createPresenter = (
-
-
-
-errorReport = (
-
-
-
-summary = (
-
-
-
-title = (
-
-
-
-)
-
-
-
-class ThreadPresenter onSubject: subj <ThreadSubject>  = ProgrammingPresenter onSubject: subj (
-|
-	protected activations
-	protected definitionHolder
-|
-)
-
-('as yet unclassified'
-
-buildActivationsHeader = (
-
-
-
-buildErrorReport = (
-
-
-
-buildMainActions = (
-
-
-
-buildMainContent = (
-
-
-
-buildMainHeader = (
-
-
-
-buildSummaryRow = (
-
-
-
-chunkSize = (
-
-
-
-compileMethod: newSource <String>
-
-
-
-definition = (
-
-
-
-expandFirst = (
-
-
-
-populateActivations = (
-
-
-
-refreshActivations = (
      i:: 0.
-
-
-
-refreshAll = (
-
-
-
-releaseUi: body = (
-
-
-
-respondToCollapseAll = (
-
-
-
-respondToExpandAll = (
-
-
-
-respondToOpenSqueakDebugger = (
-
-
-
-respondToResume = (
-
-
-
-respondToTerminate = (
-
-
-
-schedulePresentation: presenters = (
-
-
-
-secondaryActionsMenu = (
-
-
-
-title = (
-
-
-
-)'as yet unclassified'
-
-mainHeadingColor = (
-
-
-
-mainHeadingTextColor = (
-
-
-
-open = (
-
-
-
-'private'
-
-debugInSqueak = (
-
-
-
-highlight: text range: range = (
-
-
-
-releaseThread = (
-
-
-
-'testing'
-
-isAlive = (
-
-
-
-)
+	"Normally, this should not happen"
+	'ThreadPresenter>>refreshActivations : should not happen' out.
+	activations presenters: {}.
+	populateActivations.
+)
+refreshAll = (
+	activations presenters do: [:each | each refresh]
+)
+releaseUi: body = (
+	majorUpdate:
+		[activations setPresenters: {}.
+		definitionHolder content: body].
+)
+respondToCollapseAll = (
+	majorUpdate:
+		[activations presenters do: [:each | each collapse]]
+)
+respondToExpandAll = (
+	majorUpdate:
+		[activations presenters do: [:each | each expand]]
+)
+respondToOpenSqueakDebugger = (
+	releaseUi:: label: 'Debugging in Squeak debugger.'.
+	debugInSqueak
+)
+respondToResume = (
+	releaseUi:: label: 'Resuming thread.'.
+	releaseThread resume
+)
+respondToTerminate = (
+	releaseUi:: label: 'Unwinding stack.'.
+	fork: [releaseThread terminate] thenUpdateUI:
+		[releaseUi:: label: 'Thread is terminated.'].
+)
+schedulePresentation: presenters = (
+	schedule: [activations presenters: (activations presenters concatenate: presenters)]
+)
+secondaryActionsMenu = (
+	^menuWithLabelsAndActions: {
+		'Open in Squeak Debugger' -> [respondToOpenSqueakDebugger].
+	}
+)
+title = (
+	^'Stack Trace: ', subject title
+))
+class ThreadSubject onModel: t <ThreadMirror> = Subject onModel: t ()
+('as yet unclassified'
+activationsDo: action = (
+	activation activationsDo: action
+)
+createPresenter = (
+	^ThreadPresenter onSubject: self
+)
+errorReport = (
+	^String streamContents: [:s |
+		s nextPutAll: 'Please take a moment to complete the questions below and post this report to the forum: http://forums.newspeaklanguage.org/index.php?board=2.0'; cr;
+			cr; nextPutAll: 'What did you want to do?'; cr;
+			cr; nextPutAll: 'What did you do?'; cr;
+			cr; nextPutAll: 'What happened?'; cr;
+			cr; nextPutAll: 'What did you expect?'; cr;
+			cr; nextPutAll: 'Please make sure you included all relevant information so that the problem can be verified and/or reproduced.'; cr; cr;
+			cr; nextPutAll: 'DETAILS:'; cr; cr.
+		activation errorReportOn: s]
+)
+summary = (
+	^windowTitle, ' in ', model summary
+)
+title = (
+	^windowTitle
+))'as yet unclassified'
+mainHeadingColor = (
+	^Gradient from: (Color h: 0 s: 0.5 v: 0.8) to: (Color h: 0 s: 0.5 v: 0.6).
+)
+mainHeadingTextColor = (
+	^Color white
+)
+open = (
+	IDEWindow openSubjectFromBlock:
+		[:hopscotch |
+		hopscotch initialExtent: 970 @ hopscotch initialExtent y.
+		ThreadSubject onModel: thread]
+)'private'
+debugInSqueak = (
+	| context |
+	context:: activation context_slot.
+	"The Squeak debugger will schedule itself to be opened on in the Morphic UI thread."
+	SqueakDebugger
+		openOn: releaseThread squeakProcess
+		context: context
+		label: windowTitle
+		contents: nil
+		fullView: true.
+)
+highlight: text range: range = (
+	^text
+		addAttribute: TextEmphasis underlined from: range first to: range last;
+		addAttribute: TextColor red from: range first to: range last;
+		yourself
+)
+releaseThread = (
+	| theThread <ThreadMirror> |
+	theThread:: thread.
+	thread:: nil.
+	activation:: nil.
+	registry release: self.
+	^theThread
+)'testing'
+isAlive = (
+	^thread isNil not
+))

HopscotchIDEApp3.ns3

-Newspeak3
-
-'HopscotchIDE'
-
-
-
-class HopscotchIDEApp3 packageUsing: n <Namespace> = NewspeakObject (
-"Application object for the IDE.  A Newspeak application is an object that responds to the message main:args:.  The Newspeak runtime invokes main:args: with a platform object (see NsPlatform) and a collection of any runtime arguments.  An application typically responds to main:args: by instantiating and wiring together modules definitions it has stored in its slots or (in the future) modules definitions it retrives from the network via the platform object.  By convention, if a top-level class implements packageUsing:, the IDE will provide links to automatically send packageUsing: with the IDE namespace and serialize the returned object to a NOF file or package it into a Windows EXE (and someday options for Mac, Linux and the web)."
-	|
-	Tools = n HopscotchIDE IDETools.
-	Browsing = n HopscotchIDE Browsing.
-	SmalltalkBrowsing = n HopscotchIDE SmalltalkBrowsing.
-	Newspeak3Browsing = n HopscotchIDE Newspeak3Browsing.
-	MiscBrowsing = n HopscotchIDE MiscBrowsing.
-	Inspecting = n HopscotchIDE Inspecting.
-	Debugging = n HopscotchIDE Debugging.
-	ProcessFinalizer = n HopscotchIDE ProcessFinalizer.
-	WorkspaceManager = n HopscotchIDE WorkspaceManager.
-	LanguageUiDescriptionRegistry = n HopscotchIDE LanguageUiDescriptionRegistry.
-	MetadataBrowsing = n HopscotchIDE MetadataBrowsing.
-	Minitest = n Minitest Minitest.
-	MinitestUI = n Minitest MinitestUI.
-	
-	vcsLib = [n VCSLib packageUsing: n] ifError: ["VCS not in image, use nil"].
-	|
-)
-
-(
-
-
-
-class HopscotchIDE using: p <Platform> = (
-"I am to the IDE as Platform is to the runtime.  I wire together and store the IDE modules.
-"
-|| "Siml slots"
-	tools = Tools usingPlatform: p ide: self.
-	browsing = Browsing usingPlatform: p ide: self.
-	browsingST = SmalltalkBrowsing usingPlatform: p ide: self.
-	browsingNS3 = Newspeak3Browsing usingPlatform: p ide: self.
-	browsingMisc = MiscBrowsing usingPlatform: p ide: self.
-	inspection = Inspecting usingPlatform: p ide: self.
-	finalizer = ProcessFinalizer usingPlatform: p ide: self debuggingClass: Debugging.
-	debugging = Debugging usingPlatform: p ide: self.
-	theWorkspaceManager = WorkspaceManager usingPlatform: p ide: self.
-	minitest = Minitest usingPlatform: p.
-	minitestUI = MinitestUI usingPlatform: p minitest: minitest ide: self.
-	languageUiDescriptionRegistry = LanguageUiDescriptionRegistry usingPlatform: p ide: self.
-	
-	vcs = [vcsLib usingPlatform: p ide: self]ifError:["nil if unavailable"].
-	
-	defaultPopularityRecord = tools PopularityRecord new.
-||
-)
-
-('as yet unclassified'
-
-IDEWindow = (
-
-
-
-)'as yet unclassified'
-
-main: p <Platform> args: v <Tuple[String]> = (
-
-
-
-)
+Newspeak3
+'HopscotchIDE'
+class HopscotchIDEApp3 packageUsing: n <Namespace> = (
+"Application object for the IDE.  A Newspeak application is an object that responds to the message main:args:.  The Newspeak runtime invokes main:args: with a platform object (see NsPlatform) and a collection of any runtime arguments.  An application typically responds to main:args: by instantiating and wiring together modules definitions it has stored in its slots or (in the future) modules definitions it retrives from the network via the platform object.  By convention, if a top-level class implements packageUsing:, the IDE will provide links to automatically send packageUsing: with the IDE namespace and serialize the returned object to a NOF file or package it into a Windows EXE (and someday options for Mac, Linux and the web)."|
+	Tools = n HopscotchIDE IDETools.
+	Browsing = n HopscotchIDE Browsing.
+	SmalltalkBrowsing = n HopscotchIDE SmalltalkBrowsing.
+	Newspeak3Browsing = n HopscotchIDE Newspeak3Browsing.
+	MiscBrowsing = n HopscotchIDE MiscBrowsing.
+	Inspecting = n HopscotchIDE Inspecting.
+	Debugging = n HopscotchIDE Debugging.
+	ProcessFinalizer = n HopscotchIDE ProcessFinalizer.
+	WorkspaceManager = n HopscotchIDE WorkspaceManager.
+	LanguageUiDescriptionRegistry = n HopscotchIDE LanguageUiDescriptionRegistry.
+	MetadataBrowsing = n HopscotchIDE MetadataBrowsing.
+	Minitest = n Minitest Minitest.
+	MinitestUI = n Minitest MinitestUI.
+	
+	vcsLib = [n VCSLib packageUsing: n] ifError: ["VCS not in image, use nil"].
+	|)
+(
+class HopscotchIDE using: p <Platform> = (
+"I am to the IDE as Platform is to the runtime.  I wire together and store the IDE modules.
+"|| "Siml slots"
+	tools = Tools usingPlatform: p ide: self.
+	browsing = Browsing usingPlatform: p ide: self.
+	browsingST = SmalltalkBrowsing usingPlatform: p ide: self.
+	browsingNS3 = Newspeak3Browsing usingPlatform: p ide: self.
+	browsingMisc = MiscBrowsing usingPlatform: p ide: self.
+	inspection = Inspecting usingPlatform: p ide: self.
+	finalizer = ProcessFinalizer usingPlatform: p ide: self debuggingClass: Debugging.
+	debugging = Debugging usingPlatform: p ide: self.
+	theWorkspaceManager = WorkspaceManager usingPlatform: p ide: self.
+	minitest = Minitest usingPlatform: p.
+	minitestUI = MinitestUI usingPlatform: p minitest: minitest ide: self.
+	languageUiDescriptionRegistry = LanguageUiDescriptionRegistry usingPlatform: p ide: self.
+	
+	vcs = [vcsLib usingPlatform: p ide: self]ifError:["nil if unavailable"].
+	
+	defaultPopularityRecord = tools PopularityRecord new.
+||)
+('as yet unclassified'
+IDEWindow = (
+	^tools IDEWindow
+))'as yet unclassified'
+main: p <Platform> args: v <Tuple[String]> = (
+	| ide = HopscotchIDE using: p. |
+	"ide tools IDEWindow open."
+	^ide
+))
-Newspeak3
+Newspeak3
+'HopscotchIDE'
+class IDETools usingPlatform: p ide: ide = (
+"Copyright 2008 Cadence Design Systems, Inc.
+Copyright 2009-2011 Ryan Macnak and other contributors.
+   
+Licensed under the Apache License, Version 2.0 (the ''License''); you may not use this file except in compliance with the License.  You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0"|
+	"Ungood imports"
+	private Semaphore = p blackMarket Kernel Semaphore.
+	private Processor = p blackMarket Processor.
+	private Color = p blackMarket Graphics Color.
+	private SystemMetadata = p blackMarket NewsqueakMixins SystemMetadata.
+	private WorldState = p blackMarket Morphic WorldState.
+	private NewsqueakDockingBar = p blackMarket Newspeak 
+NewsqueakDockingBar.
+	private SqueakVmMirror = p blackMarket VmMirror SqueakVmMirror.
+	private Cursor = p blackMarket Graphics Cursor.
+	private NativeSession = p blackMarket NativeSession NativeSession.
+	private SmalltalkImage = p blackMarket System SmalltalkImage.
+	private OSProcess = p blackMarket OSProcess OSProcess.
+	private Smalltalk = p blackMarket Smalltalk.
+	private blackMarket = p blackMarket.
+	
+	"Doubleplusgood imports"
+	private ActiveIcon = p brazil widgets ActiveIcon.
+	private Gradient = p brazil plumbing Gradient.
+	private Menu = p brazil menus Menu.
+	private MenuItem = p brazil menus MenuItem.
+	private SeparatorItem = p brazil menus SeparatorItem.
+	private TextView = p brazil widgets TextView.
+	private OrderedCollection = p collections OrderedCollection.
+	private TextEditorFragment = p hopscotch fragments TextEditorFragment. 
+	private HopscotchImages = p hopscotch HopscotchImages.
+	private HopscotchWindow = p hopscotch core HopscotchWindow.
+	private Presenter = p hopscotch core Presenter.
+	
+	private ide = ide. 
+	private SystemscapeSubject = Delay computation: [ide browsingMisc SystemscapeSubject].
+	private ClassCategorySubject = Delay computation: [ide browsingMisc ClassCategorySubject].
+	private NSClassSubject = Delay computation: [ide browsingNS3 ClassSubject].
+	private PackageWithClassesSubject = Delay computation: [ide browsingMisc PackageWithClassesSubject].
+	private ClassCategoryDocsPresenter = Delay computation: [ide browsingMisc ClassCategoryDocsPresenter].
+	private SelectorSubject = Delay computation: [ide browsing SelectorSubject].
+	private GlobalReferencesSubject = Delay computation: [ide browsingST GlobalReferencesSubject].
+	private HomeSubject = Delay computation: [ide browsingMisc HomeSubject].
+	private HomePresenter = Delay computation: [ide browsingMisc HomePresenter].
+	private UnsavedChangesPresenter = Delay computation: [ide browsingMisc UnsavedChangesPresenter].
+	private SearchResultsSubject= Delay computation: [ide browsingMisc SearchResultsSubject].
+	|)
+(
+class ClassCommentPresenter onSubject: s = EditableDefinitionPresenter onSubject: s (
+"The subject is a ClassSubject. Displays a static text view with the text of the class comment and an ''edit'' control on the right. Clicking the control switches the view to edit mode."| showPartialIfLong::= true.
+ showingPartial |)
+('accessing'
+showFullComment = (
 
-'HopscotchIDE'
+	showPartialIfLong:: false.
+	refresh
+)
+showLessComment = (
 
-
+	showPartialIfLong:: true.
+	refresh
+)'actions'
+respondToAccept = (
+	subject classCommentText: editor textBeingAccepted. leaveEditState.
+)'definition'
+presentationDefinition = (
 
-class IDETools usingPlatform: p ide: ide = NewspeakObject (
-"Copyright 2008 Cadence Design Systems, Inc.
-Copyright 2009-2011 Ryan Macnak and other contributors.
-   
-Licensed under the Apache License, Version 2.0 (the ''License''); you may not use this file except in compliance with the License.  You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0"
-	|
-	"Ungood imports"
-	private Semaphore = p blackMarket Kernel Semaphore.
-	private Processor = p blackMarket Processor.
-	private Color = p blackMarket Graphics Color.
-	private SystemMetadata = p blackMarket NewsqueakMixins SystemMetadata.
-	private WorldState = p blackMarket Morphic WorldState.
-	private NewsqueakDockingBar = p blackMarket Newspeak 
-NewsqueakDockingBar.
-	private SqueakVmMirror = p blackMarket VmMirror SqueakVmMirror.
-	private Cursor = p blackMarket Graphics Cursor.
-	private NativeSession = p blackMarket NativeSession NativeSession.
-	private SmalltalkImage = p blackMarket System SmalltalkImage.
-	private OSProcess = p blackMarket OSProcess OSProcess.
-	private Smalltalk = p blackMarket Smalltalk.
-	private blackMarket = p blackMarket.
-	
-	"Doubleplusgood imports"
-	private ActiveIcon = p brazil widgets ActiveIcon.
-	private Gradient = p brazil plumbing Gradient.
-	private Menu = p brazil menus Menu.
-	private MenuItem = p brazil menus MenuItem.
-	private SeparatorItem = p brazil menus SeparatorItem.
-	private TextView = p brazil widgets TextView.
-	private OrderedCollection = p collections OrderedCollection.
-	private TextEditorFragment = p hopscotch fragments TextEditorFragment. 
-	private HopscotchImages = p hopscotch HopscotchImages.
-	private HopscotchWindow = p hopscotch core HopscotchWindow.
-	private Presenter = p hopscotch core Presenter.
-	
-	private ide = ide. 
-	private SystemscapeSubject = Delay computation: [ide browsingMisc SystemscapeSubject].
-	private ClassCategorySubject = Delay computation: [ide browsingMisc ClassCategorySubject].
-	private NSClassSubject = Delay computation: [ide browsingNS3 ClassSubject].
-	private PackageWithClassesSubject = Delay computation: [ide browsingMisc PackageWithClassesSubject].
-	private ClassCategoryDocsPresenter = Delay computation: [ide browsingMisc ClassCategoryDocsPresenter].
-	private SelectorSubject = Delay computation: [ide browsing SelectorSubject].
-	private GlobalReferencesSubject = Delay computation: [ide browsingST GlobalReferencesSubject].
-	private HomeSubject = Delay computation: [ide browsingMisc HomeSubject].
-	private HomePresenter = Delay computation: [ide browsingMisc HomePresenter].
-	private UnsavedChangesPresenter = Delay computation: [ide browsingMisc UnsavedChangesPresenter].
-	private SearchResultsSubject= Delay computation: [ide browsingMisc SearchResultsSubject].
-	|
-)
+	| textToDisplay |
+	textToDisplay:: retrieveComment.
+	textToDisplay isEmpty ifTrue: 
+		[textToDisplay:: '(no comment)'].
+	^column:
+		{textDisplay: textToDisplay.
+		showingPartial 
+			ifTrue: [(link: 'show full comment' action: [showFullComment]) tinyFont]
+			ifFalse: [(link: 'hide full comment' action: [showLessComment]) tinyFont].
+		}
+)'private'
+definitionText = (
+	"In this class, only used by the editor side of the presenter to get the text to show in the editor."
 
-(
+	^fullCommentText
+)
+fullCommentText = (
 
-
+	^subject classCommentText asString withBlanksTrimmed
+)
+maybePartialCommentText ^<String> = (
+	"Answer the comment text, but not more than one paragraph, and set the value of the showingPartial slot accordingly."
 
-class ProgrammingPresenter onSubject: s = Presenter onSubject: s (
-"An abstract superclass of all presenters used in programming tools. Defines all kinds of methods useful for navigation between code artifacts or their consistent display." 
-|  |
-)
+	| text paragraphs result |
+	text:: fullCommentText.
+	paragraphs:: text findTokens: {Character cr. Character lf}.
+	result:: paragraphs 
+		detect: [:some | some withBlanksTrimmed notEmpty]
+		ifNone: [String new].
+	showingPartial:: (paragraphs select: 
+		[:any |
+		any notEmpty and: [any ~= result]]) isEmpty not.
+	^showingPartial
+		ifTrue: [result, ' [...]']
+		ifFalse: [result]
+)
+retrieveComment ^<String> = (
+	"Get the text to display--either the whole thing or the first paragraph, depending on the text and the settings--and set the showingPartial slot accordingly."
 
-('as yet unclassified'
+	^showPartialIfLong
+		ifTrue: 
+			[maybePartialCommentText]
+		ifFalse: 
+			[showingPartial:: false.
+			fullCommentText]
+))
+class ClassNamePresenter onSubject: s = ProgrammingPresenter onSubject: s (
+"The subject is a ClassSubject. Displays as a row with a class icon and the name of the class as a clickable link that navigates to the class."| highlightIfRecent ::= true. |)
+('as yet unclassified'
+classLanguageIcon = (
+	^subject classUiDescription classIcon
+)
+namePart = (
 
-browseClass: aClass = (
+	| result |
+	result:: row: {
+		linkToBrowseClassOrMirror: subject model. 
+		smallBlank}.
+	(highlightIfRecent and: [subject isRecentlyVisited]) ifTrue: 
+		[result:: result color: recentlyVisitedColor].
+	^result
+)'definition'
+definition = (
 
-
+	^row: {
+		draggableImage: classLanguageIcon forSubject: subject.
+		smallBlank.
+		holder: [namePart]. "this makes it dynamically updatable"
+		smallBlank.
+		deferred:
+			[holder: 
+				[subject isAbstract
+					ifTrue: [image: HopscotchImages default tinySubclassResponsibilityImage]
+					ifFalse: [nothing]]]
+		}.
+))
+class CodeEditorFragment new = TextEditorFragment (
+"Same as TextEditorFragment, but with an editor widget specializing in displaying code (possibly with syntax highlighting)."| colorizerBlockX enterKeyResponseX |)
+('as yet unclassified'
+colorizerBlock = (
 
-browseClassMirror: aMirror = (
+	^colorizerBlockX
+)
+colorizerBlock: oneArgBlock = (
 
-
+	colorizerBlockX:: oneArgBlock.
+	hasVisual ifTrue: [editor colorizerBlock: oneArgBlock]
+)
+createEditor = (
+	"We create a colorizing CodeView rather than the stock TextView."
 
-enableInspection = (
+	editor:: CodeView new.
+	editor suppressScrollbars: true.
+	editor text: text copy.
+	editor hasEditsFromUserChannel => 
+		[:hasChanges |
+		textBeingAccepted:: editor text copy.
+		hasChanges ifTrue: [respondToChange]].
+	editor acceptKeyResponse:
+		[:defaultResponse |
+		respondToAccept].
+	editor colorizerBlock: colorizerBlockX.
+	editor enterKeyResponse: enterKeyResponseX.
+	^editor
+)
+enterKeyResponse = (
 
-
+	^enterKeyResponseX
+)
+enterKeyResponse: action <[[]]> = (
 
-inspectionHolder = (
+	enterKeyResponseX:: action.
+	hasVisual ifTrue: [editor enterKeyResponse: action]
+))
+class CodeView new = TextView (
+"Enhances TextView with the ability to color the text it displays. Colorization is performed by colorizerBlock set by the client of the view. The block accepts the text to colorize and returning the same text (but not necessarily the same instance of Text) colorized."| colorizerBlockX
+colorizationProcess 
+colorizationMutex::= Semaphore forMutualExclusion.
+ |[initialize. create. createAttributes] ifError: [])
+('accessing'
+colorizerBlock = (
 
-
+	^colorizerBlockX
+)
+colorizerBlock: oneArgBlock = (
 
-linkToBrowseClassOrMirror: aClassOrMirror = (
+	colorizerBlockX:: oneArgBlock.
+	maybeColorize.
+)
+text: newText = (
 
-
+	super text: newText asText.
+	maybeColorize
+)'parameters'
+backgroundProcessPriority ^<Integer> = (
+"The priority colorization runs on. We want it to be lower than the regular UI priority, but higher than the background (which deferred content installers run on)."
 
-respondToInspectPresenter = (
+^Processor userBackgroundPriority + 1
+)'private'
+doColorize = (
+	"Expects that the sender ensures that the colorizerBlock is present and the current text is a Text and schedules this as a background process saved in the colorizationProcess slot."
 
-
+	| startingContent newText |
+	agent isNil ifTrue: [^self].
+	startingContent:: text asString.
+	newText:: colorizerBlock clone value: text copy.
+	colorizationMutex critical:
+		[(newText isText and: [isMapped]) ifTrue:
+			[desktop scheduleUIAction:
+				[(startingContent = text asString)  ifTrue:
+					[text runs: newText runs.
+					isMapped ifTrue: [agent reemphasizeText: text]]]].
+		colorizationProcess:: nil]
+)
+maybeColorize = (
+	"Invoked after a character has been typed and the content of the view changed."
 
-subjectForClass: aClass = (
+	agent isNil ifTrue: [^self].
+	colorizerBlock notNil & text isText ifTrue:
+		[colorizationMutex critical:
+			[colorizationProcess ifNotNil: 
+				[colorizationProcess terminate].
+			colorizationProcess:: 
+				[doColorize] clone forkAt: backgroundProcessPriority]]
+)'restricted'
+acceptTextFromAgent: newText <Text | String> = (
+	"The text has been changed in the view by the user and the agent gives us the current content."
 
-
+	| tweakedText |
+	flag: #BOGUS. "the following should not be necessary when we have proper text support, but for now we should expect that an agent may pass us a naked String while the visual is holding onto a Text it wants to colorize. in that case promote the text from agent to a Text so colorization isn't disabled."
+	tweakedText:: (newText isText not and: [text isText])
+		ifTrue: [newText asText]
+		ifFalse: [newText].
+	super acceptTextFromAgent: tweakedText.
+	maybeColorize
+)
+createAgentUsing: aMapping = (
 
-testRunnerLauncherButtonAction: aBlock = (
+	super createAgentUsing: aMapping.
+	maybeColorize
+))
+class DefinitionListPresenter onSubject: s = ProgrammingPresenter onSubject: s (
+"DefinitionListPresenter is an abstract superclass of presenters that display helper ''transient'' presenters that visually appear to belong to the main list of subject presenters. One common example is a method list presenter which can at times include presenters for methods being added or residue presenters of removed methods."| prefixes content suffixes |)
+('actions'
+collapseAll = (
+	"Collapse all presenters in the content list. This operation depends on the type of content elements, so it is applicable often but not always. Still, it's handy to have it here available for reuse."
 
-
+	majorUpdate:
+		[content presenters do: [:each | each collapse]]
+)
+expandAll = (
+	"Expand all presenters in the content list. This operation depends on the type of content elements, so it is applicable often but not always. Still, it's handy to have it here available for reuse."
 
-'colors'
+	majorUpdate:
+		[content presenters do: [:each | each expand]]
+)'definition'
+contentList = (
 
-actionLinkColor = (
+	^list: [contentPresenters]
+)
+definition = (
 
-
+	prefixes:: list.
+	content:: contentList.
+	suffixes:: list.
+	^column: {
+		prefixes.
+		content.
+		suffixes.
+		}
+)'private'
+contentPresenters ^<Collection[Presenter]> = (
 
-dangerColor = (
+	^OrderedCollection new
+))
+class DefinitionResidue = ProgrammingPresenter onSubject: nil (
+""| caption definitionText extraData restoreResponse forgetResponse |)
+('as yet unclassified'
+= anotherPresenter = (
 
-
+	^self == anotherPresenter
+)
+hash = (
 
-majorHeadingColor = (
+	^self identityHash
+)'definition'
+definition = (
 
-
+	^heading:
+		(row: {
+			(label: caption) color: (Color gray: 0.7).
+			largeBlank.
+			})
+	details:
+		[TextEditorFragment new
+			text: definitionText;
+			acceptLabelText: 'restore';
+			cancelLabelText: 'forget';
+			acceptResponse: [restoreResponse valueWithPossibleArgument: self];
+			cancelResponse: [forgetResponse valueWithPossibleArgument: self];
+			enterEditState]
+))
+class DefinitionTemplate = ProgrammingPresenter onSubject:nil (
+""| caption initialText::= String new.
+ acceptResponse cancelResponse editor 
+colorizerBlock::= [ :text | text asString asText] fixTemps. "default: remove any formatting"
+ |)
+('accessing'
+text = (
 
-methodHeadingColor ^<Color> = (
+	^editor textBeingAccepted
+)'as yet unclassified'
+= anotherPresenter = (
 
-
+	^self == anotherPresenter
+)
+hash = (
 
-minorClassHeadingColor = (
+	^self identityHash
+)'definition'
+definition = (
 
-
+	^(row: {
+		mediumBlank.
+		elastic:
+			(column: {
+				smallBlank.
+				label: [caption ifNil: [String new]].
+				editorDefinition.
+				mediumBlank.
+ 			}).
+		smallBlank.
+		})
+			color: (Gradient from: (Color h: 100 s: 0.3 v: 0.9) to: (Color h: 100 s: 0.3 v: 0.8))
+)
+editorDefinition = (
 
-minorHeadingColor = (
+	editor:: CodeEditorFragment new
+		text: initialText;
+		acceptLabelText: 'save';
+		cancelLabelText: (cancelResponse ifNil: [nil] ifNotNil: ['cancel']);
+		controlBarColor: nil;
+		acceptResponse: [acceptResponse clone valueWithPossibleArgument: self];
+		cancelResponse: [cancelResponse valueWithPossibleArgument: self];
+		colorizerBlock: colorizerBlock;
+		enterEditState.
+	^editor
+))
+class EditableDefinitionPresenter onSubject: s = ProgrammingPresenter onSubject: s (
+"An abstract superclass of presenters that display some kind of a static (non-interactive) representation of their subject that can be transformed into a text editor allowing to edit the subject. It is the subclass' responsibility to define what the static representation actually looks like, how the edit state is entered, and how the text of the definition is mapped back onto the model state."| editor 
+isEditing::= false. |)
+('accessing'
+= anotherPresenter = (
 
-
+	^self == anotherPresenter
+)
+hash = (
 
-recentlyVisitedColor = (
+	^self identityHash
+)'actions'
+respondToAccept = (
 
-
+	subclassResponsibility
+)
+respondToCancel = (
 
-secondaryTextColor = (
+	leaveEditState
+)
+respondToEdit = (
 
-
+	enterEditState
+)'definition'
+definition = (
 
-'actions'
+	^holder: 
+		[isEditing
+			ifTrue: [editorDefinition]
+			ifFalse: [viewerDefinition]]
+)'private'
+definitionText = (
 
-browseClassCategory: categoryName <Symbol> = (
+	subclassResponsibility
+)
+editorDefinition = (
+	
+editor:: TextEditorFragment new.
+editor
+	text: definitionText;
+	cancelResponse: [respondToCancel];
+	acceptResponse: [respondToAccept];
+	enterEditState.
+^editor
+)
+enterEditState = (
 
-
+	isEditing:: true.
+	refresh
+)
+leaveEditState = (
 
-browseClassCategoryDocs: categoryName <Symbol> = (
+	isEditing:: false.
+	refresh
+)
+presentationDefinition = (
 
-
+	subclassResponsibility
+)
+viewerDefinition = (
+^
+	row: {
+		elastic: 
+			presentationDefinition.
+		smallBlank.
+		linkImage: HopscotchImages default editImage action: [respondToEdit]
+		}
+))
+class IDEWindow new = HopscotchWindow (
+"The HopscotchWindow specific to Smalltalk/Newspeak programming tools. Provides additional navigational aids such as the search field, as well as convenient instance creation and opening messages on the class side. For historical reasons, this is considered THE Hopscotch class."| reflectionS searchStringField metaMenuButton operateMenuButton vmMirrorS unitTestingS
+	inspectionS  |)
+('accessing'
+unitTesting ^<UnitTesting> = (
+	"Answer the UnitTesting object shared by all presenters in this browser."
 
-browseClassNamed: aSymbol = (
+	^fakeOuter unitTesting
+)'actions'
+eraseHistory = (
+"Also discard the old reflection instance."
+reflectionS:: nil.
+super eraseHistory
+)'as yet unclassified'
+addFileMenuItemsTo: menu = (
+operateMenuItemDefinitions do:
+	[:each | | item |
+	item:: each = nil
+		ifTrue: [SeparatorItem new]
+		ifFalse: [MenuItem label: each key action: [WorldState addDeferredUIMessage: [each value value]] fixTemps].
+	menu add: item].
+)
+addMenuBarItemsTo: menu <Menu> = (
+| fileMenu <Menu> |
+	fileMenu:: Menu new.
+	addFileMenuItemsTo: fileMenu.
+	menu add: (SubmenuItem new
+		label: '&File';
+		submenu: fileMenu
+		).
+	super addMenuBarItemsTo: menu.
+	menu 	add: (SubmenuItem new
+		label: '&Meta';
+		submenu: metaMenu).
+)
+addToolbarItemsTo: toolbar = (
 
-
+	super addToolbarItemsTo: toolbar.
 
-browseClassOrMirror: aClassOrMirror = (
+	toolbar addElasticBlank.
+	buildSearchStringField.
+	toolbar add: buildFindButton.
 
-
+	toolbar addBlankSize: 5.
+	toolbar add: buildMetaMenuButton.
+	toolbar add: buildOperateMenuButton.
+)
+authorizeUnsavedChanges = (
+	enterPresenter: UnsavedChangesPresenter new.
+	^false
+)
+buildMenuBar = (
+"It's the brave new world."
+^nil
+)
+confirmQuit = (
+| answer |
+answer:: MessageBox new
+	yesNoCancel: 'Save changes before quitting?';
+	open.
+answer == #yes ifTrue: [saveThenQuit].
+answer == #no ifTrue: [quit].
+)
+homePresenter = (
+	^HomePresenter
+)
+homeSubject = (
+	^HomeSubject
+)
+inspectApplication = (
+	IDEWindow openOnObject: self
+)
+inspectWindow = (
+	IDEWindow openOnVisual: window
+)
+inspection = (
+	^ide inspection
+)
+metaMenu ^ <Menu> = (
 
-browseClassReferences: aClass = (
+	^Menu new
+			add: (MenuItem label: 'Inspect Application' 
+					action: [inspectApplication]);
+			add: (MenuItem label: 'Enable Inspectors' 
+					action: [respondToEnableInspectors]);
+			add: (MenuItem label: 'Inspect Window' 
+					action: [inspectWindow]);
+			yourself
+)
+openMetaMenu = (
+| menu |
+menu:: metaMenu.
+menu ownerVisual: window.
+menu
+	openIn: window desktop 
+	at: (0 @ metaMenuButton extent y
+			translateFrom: metaMenuButton
+			to: window desktop)
+)
+openOperateMenu = (
+| menu |
+menu:: Menu forVisual: window.
+operateMenuItemDefinitions do:
+	[:each | | item |
+	item:: each = nil
+		ifTrue: [SeparatorItem new]
+		ifFalse: [MenuItem label: each key action: [WorldState addDeferredUIMessage: [each value value]] fixTemps].
+	menu add: item].
+menu 
+	openIn: window desktop 
+	at: (0 @ operateMenuButton extent y
+			translateFrom: operateMenuButton
+			to: window desktop)
+)
+operateMenuItemDefinitions ^ <Association[String, [] ]> = (
 
-
+	^Array streamContents: [:s |
+		s nextPut: 'Run App' -> [NewsqueakDockingBar someInstance runApp].
+		s nextPut: 'Open File' -> [NewsqueakDockingBar someInstance openFile].
+		s nextPut: 'Open File List'  -> [NewsqueakDockingBar someInstance openFileList].
+		s nextPut: 'Open OS File Browser' -> [NewsqueakDockingBar someInstance openOsFileBrowser].
+		s nextPut: 'Compile File' -> [NewsqueakDockingBar someInstance compileLanguageFile].
+		OSProcess isWindows ifTrue:
+			[s nextPut: nil.
+			s nextPut: 'Show Console Window' -> [NativeSession soleInstance focusSqueakWindow]].
+		s nextPut: nil.
+		s nextPut: 'Save Image'  ->[NewsqueakDockingBar someInstance saveImage].
+		s nextPut: 'Save Image As...' -> [NewsqueakDockingBar someInstance saveImageAs].
+		s nextPut: 'Quit' -> [NewsqueakDockingBar someInstance quit]
+	]
+)
+quit = (
+"Must be in Morphic UI process"
+WorldState addDeferredUIMessage:
+	[SmalltalkImage current snapshot: false andQuit: true]
+)
+respondToEnableInspectors = (
+currentPresenter withAllChildrenDo: [:each | each enableInspection]
+)
+saveThenQuit = (
+"Must be in Morphic UI process"
+WorldState addDeferredUIMessage:
+	[SmalltalkImage current snapshot: true andQuit: true]
+)
+vmMirror ^<SqueakVmMirror> = (
+	"Answer the SqueakVmMirror object shared by all presenters in this browser."
 
-browsePackage: packageName <String> = (
+	vmMirrorS ifNil:
+		[vmMirrorS:: SqueakVmMirror usingPlatform: blackMarket].
+	^vmMirrorS
+)'private-toolbar'
+buildFindButton = (
 
-
+	| button images |
+	button:: ActiveIcon new.
+	images:: HopscotchImages default.
+	button
+		image: images findSquareLeftImage;
+		hoverImage: images findSquareLeftOverImage;
+		downImage: images findSquareLeftDownImage;
+		action: [find].
+	^button 
+)
+buildMetaMenuButton = (
 
-browseReferencesToKey: aSymbol = (
+	| images |
+	metaMenuButton:: ActiveIcon new.
+	images:: HopscotchImages default.
+	metaMenuButton
+		actOnMouseDown: true;
+		image: images metaMenuImage;
+		hoverImage: images metaMenuOverImage;
+		downImage: images metaMenuDownImage;
+		action: [openMetaMenu].
+	^metaMenuButton 
+)
+buildOperateMenuButton = (
 
-
+	| images |
+	operateMenuButton:: ActiveIcon new.
+	images:: HopscotchImages default.
+	operateMenuButton
+		actOnMouseDown: true;
+		image: images operateMenuImage;
+		hoverImage: images operateMenuOverImage;
+		downImage: images operateMenuDownImage;
+		action: [openOperateMenu].
+	^operateMenuButton 
+)
+buildSearchStringField = (
 
-browseSelector: selector = (
+	searchStringField:: toolbar addNew: TextView setup:
+		[:field |
+		field text: ''.
+		field enterKeyResponse: [:defaultK | find].
+		field area width: 200].	
+	^searchStringField
+)
+find = (
 
-
+	| term |
+	Cursor wait showWhile:
+		[term:: searchStringField text asString withBlanksTrimmed.
+		term isEmpty ifTrue:
+			[^searchStringField 
+				flash;
+				text: 'type search term here'].
+		enterSubject: (SearchResultsSubject onModel: term)]
+)) : ('as yet unclassified'
+onClass: aClass = (
 
-browseSystem = (
+	^withSubjectFromBlock: 
+		[:shell | subjectForClass: aClass]
+)
+open = (
+	openSubjectFromBlock: [:me | HomeSubject new]
+)
+openOnObject: anObject = (
 
-
+	openSubjectFromBlock:
+		[:shell |
+		shell inspection ObjectSubject onModel: (shell vmMirror reflectOn: anObject)]
+)
+openOnVisual: aVisual = (
 
-confirm: label ifConfirmed: block = (
+	openSubjectFromBlock:
+		[:shell | shell inspection BrazilVisualTreeSubject onModel: aVisual]
+)
+openSubject: aSubject <Subject> = (
+	^openSubjectFromBlock: [:instance | aSubject]
+)
+openSubjectFromBlock: aBlock = (
+	^(withSubjectFromBlock: aBlock) open
+)
+subjectForClass: aClass = (
 
-
+	^aClass language classSubjectFor: aClass using: ide
+)
+withSubjectFromBlock: aBlock = (