д'Иван, это же просто замечательно то, что вы сделали! : )
Серьёзно! Давно пора было обзавестись автоматической установкой плагинов в ББ.

Почему такой грустный код? (Кстати, опечатка в комментарии.)## Код:
```
FOR k := 0 TO LEN(len) - 1 DO len[k] := 0X END; (* очистка сроки :( *)
```
Достаточно сделать len[j] := 0X сразу после WHILE. Аналогичный код есть в процедуре Load.

Вот это опасная проверка:## Код:
```
IF i = 1000 THEN
   NEW(r.buf, l);
ELSE
   r.ready := TRUE;
```
А что если у вас принятый файл окажется как раз такого размера, что закончится вместе с буфером? Маловероятно, но тем труднее будет найти ошибку. А вот здесь вы совершенно правильно проверяете:## Код:
```
IF r.rpos = LEN(r.result) THEN
   r.ready := TRUE;
   NEW(r.buf, 1000);
END
```


Замечу также мимоходом, что Reader у вас никогда не заканчивает работу:## Код:
```
IF r # NIL THEN
   Services.DoLater(r, Services.now)
END
```
Проверка всегда будет давать истину. Я бы порекомендовал проверять хотя бы ~r.ready, а по-хорошему, надо бы и при ошибках заканчивать работу. Например, если заголовок "HTTP" не найден и т.п.

В процедуре Load, я считаю, вам не нужен цикл## Код:
```
WHILE ~ stream.r.ready DO
   ProcessMessages
END;
```
Во-первых, stream.r.ready может никогда не наступить. Во-вторых, вы уже научились пользоваться Services.Action, так и пользуйтесь ими! И вообще, пользователь ведь может в процессе вашего цикла с ProcessMessages повторно нажать на коммандер. Почему бы не избавиться от глобальной переменной и не запустить несколько закачек параллельно?

В процедуре Setup рекомендую заменить код
## Код:
```
t := TextModels.dir.New();
w := t.NewWriter(NIL);
res := Load(url);
FOR i := 0 TO LEN(res) - 1 DO
   w.WriteChar(res[i]);
END;
```
на следующий:## Код:
```
res := Load(url);
t := TextModels.dir.NewFromString(res^);
```
