Safe file writing. Most common mistakes are checked against and reported before write
        operation. After that, if anything unexpected happens, user won't be left without data or
        with corrupted one as this method writes to a temporary file and then simply renames it
        (which should be atomic operation according to POSIX but who knows how Ext4 really works.
        @see: http://lwn.net/Articles/322823/).

def _writeFile(cls, filePath, content, encoding = None):
        """Safe file writing. Most common mistakes are checked against and reported before write
        operation. After that, if anything unexpected happens, user won't be left without data or
        with corrupted one as this method writes to a temporary file and then simply renames it
        (which should be atomic operation according to POSIX but who knows how Ext4 really works.
        @see: http://lwn.net/Articles/322823/)."""

        filePath = os.path.realpath(filePath)
        log.debug(_("Real file path to write: %s" % filePath))

        if encoding is None:
            encoding = File.DEFAULT_ENCODING

        try:
            encodedContent = ''.join(content).encode(encoding)
        except LookupError as msg:
            raise SubFileError(_("Unknown encoding name: '%s'.") % encoding)
        except UnicodeEncodeError:
            raise SubFileError(
                _("There are some characters in '%(file)s' that cannot be encoded to '%(enc)s'.")
                % {"file": filePath, "enc": encoding})

        tmpFilePath = "%s.tmp" % filePath
        bakFilePath = "%s.bak" % filePath
        with open(tmpFilePath, 'wb') as f:
            f.write(encodedContent)
            # ensure that all data is on disk.
            # for performance reasons, we skip os.fsync(f.fileno())
            f.flush()

        try:
            os.rename(filePath, bakFilePath)
        except FileNotFoundError:
            # there's nothing to move when filePath doesn't exist
            # note the Python bug: http://bugs.python.org/issue16074
            pass

        os.rename(tmpFilePath, filePath)

        try:
            os.unlink(bakFilePath)
        except FileNotFoundError:
            pass