protected void destroy(Throwable error) {
      if (error != null) {

        Debug.out(error);
      }

      synchronized (lock) {
        if (context_destroyed) {

          return;
        }

        context_destroyed = true;

        if (channels != null) {

          List<channel> channels_copy = new ArrayList<channel>(channels);

          for (channel c : channels_copy) {

            c.destroy();
          }
        }

        if (raf != null) {

          try {
            raf.close();

          } catch (Throwable e) {
          }

          raf = null;
        }

        if (stream_details != null) {

          try {
            stream_details.getStream().close();

          } catch (Throwable e) {

          }

          stream_details = null;
        }

        if (error != null) {

          save_to.delete();
        }
      }

      DiskManagerFileInfoStream.this.destroyed(this);
    }
    protected context() throws Exception {
      if (save_to.exists()) {

        raf = new RandomAccessFile(save_to, "r");

        stream_got_eof = true;

      } else {

        final File temp_file = new File(save_to.getAbsolutePath() + "._tmp_");

        raf = new RandomAccessFile(temp_file, "rw");

        stream_details = stream_factory.getStream(this);

        final InputStream stream = stream_details.getStream();

        new AEThread2("DMS:reader", true) {
          public void run() {
            final int BUFF_SIZE = 128 * 1024;

            byte[] buffer = new byte[BUFF_SIZE];

            try {
              while (true) {

                int len = stream.read(buffer);

                if (len <= 0) {

                  if (stream_details.hasFailed()) {

                    throw (new IOException("Stream failed"));
                  }

                  synchronized (lock) {
                    stream_got_eof = true;
                  }

                  break;
                }

                synchronized (lock) {
                  raf.seek(raf.length());

                  raf.write(buffer, 0, len);

                  for (AESemaphore waiter : waiters) {

                    waiter.release();
                  }
                }
              }
            } catch (Throwable e) {

              context.this.destroy(e);

            } finally {

              try {
                stream.close();

              } catch (Throwable e) {

              }

              Throwable failed = null;

              synchronized (lock) {
                stream_details = null;

                if (stream_got_eof) {

                  try {
                    raf.close();

                    save_to.delete();

                    temp_file.renameTo(save_to);

                    raf = new RandomAccessFile(save_to, "r");

                  } catch (Throwable e) {

                    failed = e;
                  }
                }
              }

              if (failed != null) {

                context.this.destroy(failed);
              }
            }
          }
        }.start();
      }
    }