private ProgressMonitorInputStream getMonitorableStream(File file, String message) {
    try {
      FileInputStream stream = new FileInputStream(file);
      if (stream == null) {
        System.out.println("null on " + file.getCanonicalPath());
      }
      final ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(this, message, stream);

      ProgressMonitor progress = pmis.getProgressMonitor();
      progress.setMillisToDecideToPopup(1);
      progress.setMillisToPopup(1);

      return pmis;
    } catch (IOException e) {
      showError("could not open " + file.getName());
      e.printStackTrace();
      return null;
    }
  }
  private void doSave() {
    myFile = doRead();
    if (myFile == null) {
      return;
    }

    String name = myFile.getName();
    showMessage("compressing " + name);
    String newName =
        JOptionPane.showInputDialog(this, "Name of compressed file", name + HUFF_SUFFIX);
    if (newName == null) {
      return;
    }
    String path = null;
    try {
      path = myFile.getCanonicalPath();
    } catch (IOException e) {
      showError("trouble with file canonicalizing");
      return;
    }
    int pos = path.lastIndexOf(name);
    newName = path.substring(0, pos) + newName;
    final File file = new File(newName);
    try {
      final FileOutputStream out = new FileOutputStream(file);
      ProgressMonitorInputStream temp = null;
      if (myFast) {
        temp = getMonitorableStream(getFastByteReader(myFile), "compressing bits...");
      } else {
        temp = getMonitorableStream(myFile, "compressing bits ...");
      }
      final ProgressMonitorInputStream pmis = temp;
      final ProgressMonitor progress = pmis.getProgressMonitor();
      Thread fileWriterThread =
          new Thread() {
            public void run() {
              try {
                while (!myFirstReadingDone) {
                  try {
                    sleep(100);
                  } catch (InterruptedException e) {
                    // what to do?
                    HuffViewer.this.showError("Trouble in Thread " + e);
                  }
                }
                myModel.compress(pmis, out, myForce);
              } catch (IOException e) {
                HuffViewer.this.showError("compression exception\n " + e);
                cleanUp(file);
                // e.printStackTrace();
              }
              if (progress.isCanceled()) {
                HuffViewer.this.showError("compression cancelled");
                cleanUp(file);
              }
            }
          };
      fileWriterThread.start();
    } catch (FileNotFoundException e) {
      showError("could not open " + file.getName());
      e.printStackTrace();
    }
    myFile = null;
  }
  private void doDecode() {
    File file = null;
    showMessage("uncompressing");
    try {
      int retval = ourChooser.showOpenDialog(null);
      if (retval != JFileChooser.APPROVE_OPTION) {
        return;
      }
      file = ourChooser.getSelectedFile();
      String name = file.getName();
      String uname = name;
      if (name.endsWith(HUFF_SUFFIX)) {
        uname = name.substring(0, name.length() - HUFF_SUFFIX.length()) + UNHUFF_SUFFIX;
      } else {
        uname = name + UNHUFF_SUFFIX;
      }
      String newName = JOptionPane.showInputDialog(this, "Name of uncompressed file", uname);
      if (newName == null) {
        return;
      }
      String path = file.getCanonicalPath();

      int pos = path.lastIndexOf(name);
      newName = path.substring(0, pos) + newName;
      final File newFile = new File(newName);
      ProgressMonitorInputStream temp = null;
      if (myFast) {
        temp = getMonitorableStream(getFastByteReader(file), "uncompressing bits ...");
      } else {
        temp = getMonitorableStream(file, "uncompressing bits...");
      }
      final ProgressMonitorInputStream stream = temp;

      final ProgressMonitor progress = stream.getProgressMonitor();
      final OutputStream out = new FileOutputStream(newFile);
      Thread fileReaderThread =
          new Thread() {
            public void run() {
              try {
                myModel.uncompress(stream, out);
              } catch (IOException e) {

                cleanUp(newFile);
                HuffViewer.this.showError("could not uncompress\n " + e);
                // e.printStackTrace();
              }
              if (progress.isCanceled()) {
                cleanUp(newFile);
                HuffViewer.this.showError("reading cancelled");
              }
            }
          };
      fileReaderThread.start();
    } catch (FileNotFoundException e) {
      showError("could not open " + file.getName());
      e.printStackTrace();
    } catch (IOException e) {
      showError("IOException, uncompression halted from viewer");
      e.printStackTrace();
    }
  }