void save()
  {
    try
      {
        long t1 = System.currentTimeMillis();
        if (debug)
          {
            System.err.println("DEBUG: nntp: newsrc saving " +
                               file.getPath());
          }

        int bs = (groups.size() * 20);    // guess an average line length
        FileOutputStream fw = new FileOutputStream(file);
        BufferedOutputStream writer = new BufferedOutputStream(fw, bs);
        for (Iterator i = groups.iterator(); i.hasNext();)
          {
            String group = (String) i.next();
            StringBuffer buffer = new StringBuffer(group);
            if (subs.contains(group))
              {
                buffer.append(':');
              }
            else
              {
                buffer.append('!');
              }
            Object r = lines.get(group);
            if (r instanceof String)
              {
                buffer.append((String) r);
              }
            else
              {
                RangeList ranges = (RangeList) r;
                if (ranges != null)
                  {
                    buffer.append(ranges.toString());
                  }
              }
            buffer.append('\n');

            byte[] bytes = buffer.toString().getBytes(NEWSRC_ENCODING);
            writer.write(bytes);
          }
        writer.flush();
        writer.close();

        long t2 = System.currentTimeMillis();
        if (debug)
          {
            System.err.println("DEBUG: nntp: newsrc save: " +
                               groups.size() + " groups in " +
                               (t2 - t1) + "ms");
          }
      }
    catch (IOException e)
      {
        System.err.println("WARNING: nntp: unable to save newsrc file");
        if (debug)
          {
            e.printStackTrace(System.err);
          }
      }
    dirty = false;
  }