@Override
	public void run() {
		for (;;) {
			synchronized (iter) {
				if (iter.hasNext()) {
					currentZipEntry = iter.next();
				} else {
					wr.getWw().threadOutMessage("Finished", id, 4);
					return;
				}
			}
			// Report what's happening
			if (!config.isForceRun()) {
				wr.getWw().threadOutMessage(" " + currentZipEntry, id, 4);
			} else {
				wr.getWw().threadOutMessage(currentZipEntry + " (forced)", id,
						4);
			}
			// If already run, loop back and find a new zip
			if (1 != currentZipEntry.getValue() || config.isForceRun()) {
				// Load data
				df.load(currentZipEntry.getKey());

				// Write data
				try {
					synchronized (db) {
						if (df.valid) {
							db.storeForecast(df.forecast1);
							db.storeForecast(df.forecast3);
							db.storePast(df.past);
							db.updateZipSuccess(currentZipEntry.getKey());

						} else {
							// Update a failure to load data
							db.updateZipFail(currentZipEntry.getKey());
						}

						// Commit
						db.commit();
					}
				} catch (Exception e) {
					wr.setFail();
					wr.getWw().threadOutMessage(currentZipEntry + " failed",
							id, 2);
				}
				if (Thread.interrupted() || config.isStopProgram()) {
					break;
				}
			}
		}
		wr.getWw().threadOutMessage("Finished", id, 3);
	}