@Override
  public void close() throws IOException {
    if (myClosed) return;
    myClosed = true;

    try {
      myOutputStream.close();
    }
    catch (IOException e) {
      deleteFile(myTemp);
      error("Cannot write a temporary file " + myTemp.getFileName(), e);
    }

    if (myFailed) {
      deleteFile(myTemp);
      error("Cannot write a temporary file " + myTemp.getFileName(), null);
    }

    Path backup = null;
    if (Files.exists(myTarget)) {
      backup = myTarget.getFileSystem().getPath(myTarget + BACKUP_EXT);
      try {
        Files.move(myTarget, backup, RENAME);
      }
      catch (IOException e) {
        deleteFile(myTemp);
        error("Cannot create a backup file " + backup.getFileName() + ".\n" +
              "The original file is unchanged; new data are written into " + myTemp.getFileName(), e);
      }
    }

    try {
      Files.move(myTemp, myTarget, RENAME);
    }
    catch (IOException e) {
      if (backup == null) {
        error("Cannot rename a temporary file " + myTemp.getFileName(), e);
      }

      try {
        Files.move(backup, myTarget, RENAME);
      }
      catch (IOException ee) {
        error("Cannot rename a temporary file " + myTemp.getFileName() + ".\n" +
              "The original file was renamed into " + backup.getFileName() + "; new data are written into " + myTemp.getFileName(), e);
      }

      error("Cannot rename a temporary file " + myTemp.getFileName() + ".\n" +
            "The original file was restored from a backup; new data are written into " + myTemp.getFileName(), e);
    }

    if (backup != null) {
      deleteFile(backup);
    }
  }
@Override
  public void close()