public static boolean renameTo(File from, File to) {
		RandomAccessFile raf = null;
		FileOutputStream fos = null;
		FileInputStream fis = null;

		try {
			// D.out("moving " + from + " to " + to);

			// do it the API way

			to.delete();
			boolean ok = from.renameTo(to);

			if (ok) {
				// D.out("(normal) moved " + from + " to " + to);
				return true;
			}

			// renaming did not work. we try the gcHack and try again
			gcHack();
			ok = from.renameTo(to);

			if (ok) {
				D.out("(Windows GC hack) moved " + from + " to " + to);
				return true;
			}

			// we may not need these because we have gcHack ()

			D
					.out("Moving via file.move did not move, even not with the System.gc() hack. Copying manually now and then deleting.");

			// not renamed properly, do it manually
			raf = new RandomAccessFile(to, "rw");
			raf.setLength(from.length());
			raf.getFD().sync();
			fos = new FileOutputStream(to);

			fis = new FileInputStream(from);

			FileChannel outChannel = fos.getChannel();
			FileChannel inChannel = fis.getChannel();

			long length = from.length();
			long toWrite = length;

			while (toWrite > 0) {
				inChannel.position(length - toWrite);
				long written = inChannel.transferTo(inChannel.position(),
						toWrite, outChannel);

				if (written == -1)
					throw new Exception("Copy failure");

				toWrite -= written;
			}

			outChannel.close();
			inChannel.close();
			raf.close();

			// delete from file
			gcHack();
			from.delete();

			// we do not do deleteOnExit here because the caller may not want
			// this
			D.out("(manual) moved " + from + " to " + to);
			return true;

		} catch (Exception e) {
			D.out(e.getClass().getSimpleName() + ": " + e.getMessage());
			e.printStackTrace();
			return false;
		} finally {
			try {
				if (fos != null)
					fos.close();

				if (fis != null)
					fis.close();

				if (raf != null)
					raf.close();
			} catch (Exception e) {

			}
		}

	}