public void endThreadTransaction(int maxDelay) {
		if (multiclientSupport) {
			if (maxDelay != Integer.MAX_VALUE) {
				throw new IllegalArgumentException(
						"Delay is not supported for global transactions");
			}

			synchronized (transactionMonitor) {
				transactionLock.unlock();

				if (nNestedTransactions != 0) { // may be everything is already
												// aborted
					if (nNestedTransactions == 1) {
						commit();
						pool.flush();
						file.unlock();
					}

					nNestedTransactions -= 1;
				}
			}

			return;
		}

		ThreadTransactionContext ctx = getTransactionContext();

		if (ctx.nested != 0) { // serializable transaction
			if (--ctx.nested == 0) {
				ArrayList modified = ctx.modified;
				ArrayList deleted = ctx.deleted;
				Map locked = ctx.locked;

				synchronized (backgroundGcMonitor) {
					synchronized (this) {
						synchronized (objectCache) {
							for (int i = modified.size(); --i >= 0;) {
								store(modified.get(i));
							}

							for (int i = deleted.size(); --i >= 0;) {
								deallocateObject0(deleted.get(i));
							}

							if (modified.size() + deleted.size() > 0) {
								commit0();
							}
						}
					}
				}

				Iterator iterator = locked.values().iterator();

				while (iterator.hasNext()) {
					((IResource) iterator.next()).reset();
				}

				modified.clear();
				deleted.clear();
				locked.clear();
			}
		}
		else { // exclusive or cooperative transaction
			synchronized (transactionMonitor) {
				transactionLock.unlock();

				if (nNestedTransactions != 0) { // may be everything is already
												// aborted
					if (--nNestedTransactions == 0) {
						nCommittedTransactions += 1;
						commit();
						scheduledCommitTime = Long.MAX_VALUE;

						if (nBlockedTransactions != 0) {
							transactionMonitor.notifyAll();
						}
					}
					else {
						if (maxDelay != Integer.MAX_VALUE) {
							long nextCommit = System.currentTimeMillis()
									+ maxDelay;
							if (nextCommit < scheduledCommitTime) {
								scheduledCommitTime = nextCommit;
							}

							if (maxDelay == 0) {
								int n = nCommittedTransactions;
								nBlockedTransactions += 1;

								do {
									try {
										transactionMonitor.wait();
									}
									catch (InterruptedException x) {}
								}
								while (nCommittedTransactions == n);

								nBlockedTransactions -= 1;
							}
						}
					}
				}
			}
		}
	}