requires: {#Collection}. provides: {#ExtensibleCollection}. collections addSlot: #ExtensibleCollection valued: Collection derive. e@(ExtensibleCollection traits) add: obj [ overrideThis ]. c@(ExtensibleCollection traits) newWith: obj [| newC | newC: c newEmpty. newC add: obj. newC ]. c@(ExtensibleCollection traits) newWithAll: d@(Collection traits) "Make a new collection of kind c and stuff in all of d's elements." [| newC | newC: (c newSizeOf: d). newC addAll: d newC ]. e@(ExtensibleCollection traits) add: obj ifPresent: block "Add the object only if it doesn't already occur in c. If it already does occur, perform the alternative given." [ (e includes: obj) ifFalse: [e add: obj]. block value ]. e@(ExtensibleCollection traits) include: obj "Add the object only if it doesn't already occur in c." [ e add: obj ifPresent: [] ]. e@(ExtensibleCollection traits) add: obj withOccurrences: n@(Integer traits) "Add n occurrences of an object." [ n timesRepeat: [e add: obj]. obj ]. e@(ExtensibleCollection traits) addAll: d@(Collection traits) "Add each element of d to e." [ d do: [| :each | e add: each]. d ]. e@(ExtensibleCollection traits) removeAll: d@(Collection traits) "Remove all elements of d from c. Removing all from itself has to be separately handled." [| itemsToRemove | itemsToRemove: (e == d ifTrue: [d copy] ifFalse: [d]). itemsToRemove do: [| :each | e remove: each]. itemsToRemove ]. e@(ExtensibleCollection traits) removeAllSuchThat: test "Remove all elements that satisfy the test. Copy the collection since some subclasses re-order their elements on removal." [ e copy do: [| :each | (test value: each) ifTrue: [e remove: each]]. e ]. e@(ExtensibleCollection traits) remove: obj [ e remove: obj ifAbsent: [] ]. c@(Collection traits) collect: block into: result@(ExtensibleCollection traits) "Similar to collect:, but answers the given collection with the results of applying the block to each element added." [ c do: [| :each | result add: (block value: each)]. result ].