In general I would agree:
Though in order to use the class query you have the change  to namespace "%SYS" and  back.
As the query is predefined you finally build your own lookup list which is a copy of the original global.

Anyhow this would provide the required result:

     kill roles
    set roles=""
    new $namespace
    zn "%SYS"
    set rs=##class(%ResultSet).%New("Security.Roles:ListAll1")
    set tSC=rs.Execute()
    if tSC
       {
        while rs.Next() {
            set role=rs.Get("Name")
            write ">",role,! ;; just for display
            set roles($zcvt(role,"L"))=""
       }
     set rs=""                       ;; for save return from "%SYS"
     zw roles                        ;; for demo
     set list2=$lfs(input,"CN=")
     for i=2:1:$LL(list2) {
        set CN=$p($li(list2,i),",") ;; get 1st piece
        set CN=$zcvt(CN,"L") ;; lower case required..v
        set exists=''$d(roles(CN))
        write !,i," ",exists," ",CN ;; for debugging and demo
        if exists write " role found"
        }
     quit                            ;; get back to original namespace

what is this ?  a String or a JSON object ,  or a fixed sequence of (CN=  ,OU=,  DC=, DC= )
there is no obvious groupIng by a separator visible.
You may start by

set list=$lfs($p($p(input,"{",2),"}"))
zw list
list=$lb("CN=Access.Ensemble.Developer.User","OU=Access Groups","DC=OSUMC","DC=EDU"," CN=[CPD Admin]","OU=Distribution Lists","DC=OSUMC","DC=EDU"," CN=[MUSE_Access]","OU=Distribution Lists","DC=OSUMC","DC=EDU"," CN=[IT eMaterials]","OU=Distribution Lists","DC=OSUMC","DC=EDU...")

 

But instead of an unstructured string you have an unstructured list  

George, Gordon
Interesting info on Upgrade2016.1  This seems to by some fake news.
Since the class is there om 2017.2 and even in IRIS2018.1
http://docs.intersystems.com/iris20181/csp/documatic/%25CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%25SYS&CLASSNAME=%25CSP.Stream

The Type set fails because %CSP.Stream is just an abstract class. 
Like %CSP.Page you have to create the real object yourself as %CSP.CharacterStream or %CSP.BinaryStream
 

a little bit simplified for retyping in terminal:

set req = ##class(%CSP.Request).%New()
set cont=req.Content zw cont   ; MO AUTOMATIC OBJECT BEAUSE ABSTRACT !!
cont=""
set cont=##class(%CSP.CharacterStream).%New()  zw cont  ; NOW WE HAVE AN OBJECT
cont=<OBJECT REFERENCE>[5@%CSP.CharacterStream]
+----------------- general information ---------------
|      oref value: 5
|      class name: %CSP.CharacterStream
| reference count: 2
+----------------- attribute values ------------------
|     (%Concurrency) = 1
|    (%LastModified) = ""
|          %Location = ""  <Get,Set>
|         (%LockRef) = ""
|          (%Locked) = 0
|              AtEnd = 0
|           (Buffer) = ""
|           (IOSize) = 0
|                 Id = ""
|     LineTerminator = $c(13,10)  <Set>
|        (MaxNodeNo) = 0
|             (Mode) = 0
|           (NodeNo) = 0
|         (Position) = 1
|        (StoreNode) = ""
|        (StoreRoot) = "^CacheStream"
|         (TempNode) = ""
+--------------- calculated references ---------------
|            CharSet   <Get,Set>
|        ContentType   <Get,Set>
|            Expires   <Get,Set>
|           FileName   <Get,Set>
|            Headers   <Get,Set>
|       LastModified   <Get>
|        MimeSection   <Get,Set>
|               Size   <Get>
|        (StoreGlvn)   <Get>
|         (TempGlvn)   <Get>
+-----------------------------------------------------
set cont.ContentType=
"application/json"

; and so on ....

HTH

Digging around working sets I found them unable to cover package  structures:
packages seem to be implemented as kind of sub-directory. 

You see the same effect in editor pane. The package is only visible in mouseOver event.
  

You only see the packages if you click the down arrow in right upper corner and "Edit Working Set".

For "TZ = TimeZone" I googled around Eclipse and opened a can of worms. With no answer.

I probably don't understand your expectation.

You upload typically an image or something similar that the browser
can display as part of the article, questions, answer, comment you write.
And that works excellent.

If this is something else e.g. some binary stuff, or Word.doc or Excel it may fail.
What type of file would you expect to upload ?  

Oliver,

this turned out to be somewhat more tricky than expected.
The way you used stream.FindAt(...)  returns the size of the gap between the last found occurrence and the next.
So you have to add the size of your search string for each loop to get closer to your file size

so it might be easier to do it this way:

set last=1
for  set i=stream.FindAt(last,"Invalid password") quit:i<0  set last=i

this might be closer but definitely smaller than the total size  

it says:

If it does not find the target string then return -1

So what you get in i is the last start of your search string

              Which is 2491024949 - 2442920326 = 48104623 from end.
It's almost the same as your first occurrence at 49134354. Looks feasible.

To get the file size as you expect the LAST search string must have been  starting
AT 
the end of your file. Which is a contradiction.