diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
index a13a4ff..2d730a1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AbstractAdvertiseRefsHook.java
@@ -63,7 +63,7 @@ public void advertiseRefs(UploadPack uploadPack)
 				uploadPack.getRepository(), uploadPack.getRevWalk()));
 	}
 
-	public void advertiseRefs(ReceivePack receivePack)
+	public void advertiseRefs(BaseReceivePack receivePack)
 			throws ServiceMayNotContinueException {
 		Map<String, Ref> refs = getAdvertisedRefs(receivePack.getRepository(),
 				receivePack.getRevWalk());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
index 0f76f67..c3af74a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHook.java
@@ -53,14 +53,14 @@ public interface AdvertiseRefsHook {
 	 * <p>
 	 * The method implementations do nothing to preserve the default behavior; see
 	 * {@link UploadPack#setAdvertisedRefs(java.util.Map)} and
-	 * {@link ReceivePack#setAdvertisedRefs(java.util.Map,java.util.Set)}.
+	 * {@link BaseReceivePack#setAdvertisedRefs(java.util.Map,java.util.Set)}.
 	 */
 	public static final AdvertiseRefsHook DEFAULT = new AdvertiseRefsHook() {
 		public void advertiseRefs(UploadPack uploadPack) {
 			// Do nothing.
 		}
 
-		public void advertiseRefs(ReceivePack receivePack) {
+		public void advertiseRefs(BaseReceivePack receivePack) {
 			// Do nothing.
 		}
 	};
@@ -81,11 +81,11 @@ public void advertiseRefs(UploadPack uploadPack)
 	 * Advertise refs for receive-pack.
 	 *
 	 * @param receivePack instance on which to call
-	 *            {@link ReceivePack#setAdvertisedRefs(java.util.Map,java.util.Set)}
+	 *            {@link BaseReceivePack#setAdvertisedRefs(java.util.Map,java.util.Set)}
 	 *            if necessary.
 	 * @throws ServiceMayNotContinueException
 	 *             abort; the message will be sent to the user.
 	 */
-	public void advertiseRefs(ReceivePack receivePack)
+	public void advertiseRefs(BaseReceivePack receivePack)
 			throws ServiceMayNotContinueException;
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
index ec1e62d..00942ab 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AdvertiseRefsHookChain.java
@@ -51,8 +51,8 @@
  * Hooks are run in the order passed to the constructor. A hook may inspect or
  * modify the results of the previous hooks in the chain by calling
  * {@link UploadPack#getAdvertisedRefs()}, or
- * {@link ReceivePack#getAdvertisedRefs()} or
- * {@link ReceivePack#getAdvertisedObjects()}.
+ * {@link BaseReceivePack#getAdvertisedRefs()} or
+ * {@link BaseReceivePack#getAdvertisedObjects()}.
  */
 public class AdvertiseRefsHookChain implements AdvertiseRefsHook {
 	private final AdvertiseRefsHook[] hooks;
@@ -79,7 +79,7 @@ else if (i == 1)
 			return new AdvertiseRefsHookChain(newHooks, i);
 	}
 
-	public void advertiseRefs(ReceivePack rp)
+	public void advertiseRefs(BaseReceivePack rp)
 			throws ServiceMayNotContinueException {
 		for (int i = 0; i < count; i++)
 			hooks[i].advertiseRefs(rp);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
new file mode 100644
index 0000000..c0d44b1
--- /dev/null
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BaseReceivePack.java
@@ -0,0 +1,1294 @@
+/*
+ * Copyright (C) 2008-2010, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.transport;
+
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_DELETE_REFS;
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_OFS_DELTA;
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_REPORT_STATUS;
+import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;
+import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA;
+import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS;
+import static org.eclipse.jgit.transport.SideBandOutputStream.MAX_BUF;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.errors.PackProtocolException;
+import org.eclipse.jgit.internal.JGitText;
+import org.eclipse.jgit.lib.Config;
+import org.eclipse.jgit.lib.Config.SectionParser;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.NullProgressMonitor;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.ObjectIdSubclassMap;
+import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.ProgressMonitor;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.ObjectWalk;
+import org.eclipse.jgit.revwalk.RevBlob;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevFlag;
+import org.eclipse.jgit.revwalk.RevObject;
+import org.eclipse.jgit.revwalk.RevSort;
+import org.eclipse.jgit.revwalk.RevTree;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.storage.file.PackLock;
+import org.eclipse.jgit.transport.ReceiveCommand.Result;
+import org.eclipse.jgit.util.io.InterruptTimer;
+import org.eclipse.jgit.util.io.TimeoutInputStream;
+import org.eclipse.jgit.util.io.TimeoutOutputStream;
+
+/**
+ * Base implementation of the side of a push connection that receives objects.
+ * <p>
+ * Contains high-level operations for initializing and closing streams,
+ * advertising refs, reading commands, and receiving and applying a pack.
+ * Subclasses compose these operations into full service implementations.
+ */
+public abstract class BaseReceivePack {
+	/** Data in the first line of a request, the line itself plus capabilities. */
+	public static class FirstLine {
+		private final String line;
+		private final Set<String> capabilities;
+
+		/**
+		 * Parse the first line of a receive-pack request.
+		 *
+		 * @param line
+		 *            line from the client.
+		 */
+		public FirstLine(String line) {
+			final HashSet<String> caps = new HashSet<String>();
+			final int nul = line.indexOf('\0');
+			if (nul >= 0) {
+				for (String c : line.substring(nul + 1).split(" "))
+					caps.add(c);
+				this.line = line.substring(0, nul);
+			} else
+				this.line = line;
+			this.capabilities = Collections.unmodifiableSet(caps);
+		}
+
+		/** @return non-capabilities part of the line. */
+		public String getLine() {
+			return line;
+		}
+
+		/** @return capabilities parsed from the line. */
+		public Set<String> getCapabilities() {
+			return capabilities;
+		}
+	}
+
+	/** Database we write the stored objects into. */
+	protected final Repository db;
+
+	/** Revision traversal support over {@link #db}. */
+	protected final RevWalk walk;
+
+	/**
+	 * Is the client connection a bi-directional socket or pipe?
+	 * <p>
+	 * If true, this class assumes it can perform multiple read and write cycles
+	 * with the client over the input and output streams. This matches the
+	 * functionality available with a standard TCP/IP connection, or a local
+	 * operating system or in-memory pipe.
+	 * <p>
+	 * If false, this class runs in a read everything then output results mode,
+	 * making it suitable for single round-trip systems RPCs such as HTTP.
+	 */
+	protected boolean biDirectionalPipe = true;
+
+	/** Should an incoming transfer validate objects? */
+	protected boolean checkReceivedObjects;
+
+	/** Should an incoming transfer permit create requests? */
+	protected boolean allowCreates;
+
+	/** Should an incoming transfer permit delete requests? */
+	protected boolean allowDeletes;
+
+	/** Should an incoming transfer permit non-fast-forward requests? */
+	protected boolean allowNonFastForwards;
+
+	private boolean allowOfsDelta;
+
+	/** Identity to record action as within the reflog. */
+	private PersonIdent refLogIdent;
+
+	/** Hook used while advertising the refs to the client. */
+	private AdvertiseRefsHook advertiseRefsHook;
+
+	/** Filter used while advertising the refs to the client. */
+	private RefFilter refFilter;
+
+	/** Timeout in seconds to wait for client interaction. */
+	private int timeout;
+
+	/** Timer to manage {@link #timeout}. */
+	private InterruptTimer timer;
+
+	private TimeoutInputStream timeoutIn;
+
+	// Original stream passed to init(), since rawOut may be wrapped in a
+	// sideband.
+	private OutputStream origOut;
+
+	/** Raw input stream. */
+	protected InputStream rawIn;
+
+	/** Raw output stream. */
+	protected OutputStream rawOut;
+
+	/** Optional message output stream. */
+	protected OutputStream msgOut;
+
+	/** Packet line input stream around {@link #rawIn}. */
+	protected PacketLineIn pckIn;
+
+	/** Packet line output stream around {@link #rawOut}. */
+	protected PacketLineOut pckOut;
+
+	private final MessageOutputWrapper msgOutWrapper = new MessageOutputWrapper();
+
+	private PackParser parser;
+
+	/** The refs we advertised as existing at the start of the connection. */
+	protected Map<String, Ref> refs;
+
+	/** All SHA-1s shown to the client, which can be possible edges. */
+	protected Set<ObjectId> advertisedHaves;
+
+	/** Capabilities requested by the client. */
+	protected Set<String> enabledCapabilities;
+
+	private List<ReceiveCommand> commands;
+
+	private StringBuilder advertiseError;
+
+	/** If {@link BasePackPushConnection#CAPABILITY_REPORT_STATUS} is enabled. */
+	protected boolean reportStatus;
+
+	/** If {@link BasePackPushConnection#CAPABILITY_SIDE_BAND_64K} is enabled. */
+	protected boolean sideBand;
+
+	/** Lock around the received pack file, while updating refs. */
+	private PackLock packLock;
+
+	private boolean checkReferencedIsReachable;
+
+	/** Git object size limit */
+	private long maxObjectSizeLimit;
+
+	/**
+	 * Create a new pack receive for an open repository.
+	 *
+	 * @param into
+	 *            the destination repository.
+	 */
+	protected BaseReceivePack(final Repository into) {
+		db = into;
+		walk = new RevWalk(db);
+
+		final ReceiveConfig cfg = db.getConfig().get(ReceiveConfig.KEY);
+		checkReceivedObjects = cfg.checkReceivedObjects;
+		allowCreates = cfg.allowCreates;
+		allowDeletes = cfg.allowDeletes;
+		allowNonFastForwards = cfg.allowNonFastForwards;
+		allowOfsDelta = cfg.allowOfsDelta;
+		advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
+		refFilter = RefFilter.DEFAULT;
+		advertisedHaves = new HashSet<ObjectId>();
+	}
+
+	/** Configuration for receive operations. */
+	protected static class ReceiveConfig {
+		static final SectionParser<ReceiveConfig> KEY = new SectionParser<ReceiveConfig>() {
+			public ReceiveConfig parse(final Config cfg) {
+				return new ReceiveConfig(cfg);
+			}
+		};
+
+		final boolean checkReceivedObjects;
+
+		final boolean allowCreates;
+
+		final boolean allowDeletes;
+
+		final boolean allowNonFastForwards;
+
+		final boolean allowOfsDelta;
+
+		ReceiveConfig(final Config config) {
+			checkReceivedObjects = config.getBoolean("receive", "fsckobjects",
+					false);
+			allowCreates = true;
+			allowDeletes = !config.getBoolean("receive", "denydeletes", false);
+			allowNonFastForwards = !config.getBoolean("receive",
+					"denynonfastforwards", false);
+			allowOfsDelta = config.getBoolean("repack", "usedeltabaseoffset",
+					true);
+		}
+	}
+
+	/**
+	 * Output stream that wraps the current {@link #msgOut}.
+	 * <p>
+	 * We don't want to expose {@link #msgOut} directly because it can change
+	 * several times over the course of a session.
+	 */
+	class MessageOutputWrapper extends OutputStream {
+		@Override
+		public void write(int ch) {
+			if (msgOut != null) {
+				try {
+					msgOut.write(ch);
+				} catch (IOException e) {
+					// Ignore write failures.
+				}
+			}
+		}
+
+		@Override
+		public void write(byte[] b, int off, int len) {
+			if (msgOut != null) {
+				try {
+					msgOut.write(b, off, len);
+				} catch (IOException e) {
+					// Ignore write failures.
+				}
+			}
+		}
+
+		@Override
+		public void write(byte[] b) {
+			write(b, 0, b.length);
+		}
+
+		@Override
+		public void flush() {
+			if (msgOut != null) {
+				try {
+					msgOut.flush();
+				} catch (IOException e) {
+					// Ignore write failures.
+				}
+			}
+		}
+	}
+
+	/** @return the process name used for pack lock messages. */
+	protected abstract String getLockMessageProcessName();
+
+	/** @return the repository this receive completes into. */
+	public final Repository getRepository() {
+		return db;
+	}
+
+	/** @return the RevWalk instance used by this connection. */
+	public final RevWalk getRevWalk() {
+		return walk;
+	}
+
+	/**
+	 * Get refs which were advertised to the client.
+	 *
+	 * @return all refs which were advertised to the client, or null if
+	 *         {@link #setAdvertisedRefs(Map, Set)} has not been called yet.
+	 */
+	public final Map<String, Ref> getAdvertisedRefs() {
+		return refs;
+	}
+
+	/**
+	 * Set the refs advertised by this ReceivePack.
+	 * <p>
+	 * Intended to be called from a {@link PreReceiveHook}.
+	 *
+	 * @param allRefs
+	 *            explicit set of references to claim as advertised by this
+	 *            ReceivePack instance. This overrides any references that
+	 *            may exist in the source repository. The map is passed
+	 *            to the configured {@link #getRefFilter()}. If null, assumes
+	 *            all refs were advertised.
+	 * @param additionalHaves
+	 *            explicit set of additional haves to claim as advertised. If
+	 *            null, assumes the default set of additional haves from the
+	 *            repository.
+	 */
+	public void setAdvertisedRefs(Map<String, Ref> allRefs, Set<ObjectId> additionalHaves) {
+		refs = allRefs != null ? allRefs : db.getAllRefs();
+		refs = refFilter.filter(refs);
+
+		Ref head = refs.get(Constants.HEAD);
+		if (head != null && head.isSymbolic())
+			refs.remove(Constants.HEAD);
+
+		for (Ref ref : refs.values()) {
+			if (ref.getObjectId() != null)
+				advertisedHaves.add(ref.getObjectId());
+		}
+		if (additionalHaves != null)
+			advertisedHaves.addAll(additionalHaves);
+		else
+			advertisedHaves.addAll(db.getAdditionalHaves());
+	}
+
+	/**
+	 * Get objects advertised to the client.
+	 *
+	 * @return the set of objects advertised to the as present in this repository,
+	 *         or null if {@link #setAdvertisedRefs(Map, Set)} has not been called
+	 *         yet.
+	 */
+	public final Set<ObjectId> getAdvertisedObjects() {
+		return advertisedHaves;
+	}
+
+	/**
+	 * @return true if this instance will validate all referenced, but not
+	 *         supplied by the client, objects are reachable from another
+	 *         reference.
+	 */
+	public boolean isCheckReferencedObjectsAreReachable() {
+		return checkReferencedIsReachable;
+	}
+
+	/**
+	 * Validate all referenced but not supplied objects are reachable.
+	 * <p>
+	 * If enabled, this instance will verify that references to objects not
+	 * contained within the received pack are already reachable through at least
+	 * one other reference displayed as part of {@link #getAdvertisedRefs()}.
+	 * <p>
+	 * This feature is useful when the application doesn't trust the client to
+	 * not provide a forged SHA-1 reference to an object, in an attempt to
+	 * access parts of the DAG that they aren't allowed to see and which have
+	 * been hidden from them via the configured {@link AdvertiseRefsHook} or
+	 * {@link RefFilter}.
+	 * <p>
+	 * Enabling this feature may imply at least some, if not all, of the same
+	 * functionality performed by {@link #setCheckReceivedObjects(boolean)}.
+	 * Applications are encouraged to enable both features, if desired.
+	 *
+	 * @param b
+	 *            {@code true} to enable the additional check.
+	 */
+	public void setCheckReferencedObjectsAreReachable(boolean b) {
+		this.checkReferencedIsReachable = b;
+	}
+
+	/**
+	 * @return true if this class expects a bi-directional pipe opened between
+	 *         the client and itself. The default is true.
+	 */
+	public boolean isBiDirectionalPipe() {
+		return biDirectionalPipe;
+	}
+
+	/**
+	 * @param twoWay
+	 *            if true, this class will assume the socket is a fully
+	 *            bidirectional pipe between the two peers and takes advantage
+	 *            of that by first transmitting the known refs, then waiting to
+	 *            read commands. If false, this class assumes it must read the
+	 *            commands before writing output and does not perform the
+	 *            initial advertising.
+	 */
+	public void setBiDirectionalPipe(final boolean twoWay) {
+		biDirectionalPipe = twoWay;
+	}
+
+	/**
+	 * @return true if this instance will verify received objects are formatted
+	 *         correctly. Validating objects requires more CPU time on this side
+	 *         of the connection.
+	 */
+	public boolean isCheckReceivedObjects() {
+		return checkReceivedObjects;
+	}
+
+	/**
+	 * @param check
+	 *            true to enable checking received objects; false to assume all
+	 *            received objects are valid.
+	 */
+	public void setCheckReceivedObjects(final boolean check) {
+		checkReceivedObjects = check;
+	}
+
+	/** @return true if the client can request refs to be created. */
+	public boolean isAllowCreates() {
+		return allowCreates;
+	}
+
+	/**
+	 * @param canCreate
+	 *            true to permit create ref commands to be processed.
+	 */
+	public void setAllowCreates(final boolean canCreate) {
+		allowCreates = canCreate;
+	}
+
+	/** @return true if the client can request refs to be deleted. */
+	public boolean isAllowDeletes() {
+		return allowDeletes;
+	}
+
+	/**
+	 * @param canDelete
+	 *            true to permit delete ref commands to be processed.
+	 */
+	public void setAllowDeletes(final boolean canDelete) {
+		allowDeletes = canDelete;
+	}
+
+	/**
+	 * @return true if the client can request non-fast-forward updates of a ref,
+	 *         possibly making objects unreachable.
+	 */
+	public boolean isAllowNonFastForwards() {
+		return allowNonFastForwards;
+	}
+
+	/**
+	 * @param canRewind
+	 *            true to permit the client to ask for non-fast-forward updates
+	 *            of an existing ref.
+	 */
+	public void setAllowNonFastForwards(final boolean canRewind) {
+		allowNonFastForwards = canRewind;
+	}
+
+	/** @return identity of the user making the changes in the reflog. */
+	public PersonIdent getRefLogIdent() {
+		return refLogIdent;
+	}
+
+	/**
+	 * Set the identity of the user appearing in the affected reflogs.
+	 * <p>
+	 * The timestamp portion of the identity is ignored. A new identity with the
+	 * current timestamp will be created automatically when the updates occur
+	 * and the log records are written.
+	 *
+	 * @param pi
+	 *            identity of the user. If null the identity will be
+	 *            automatically determined based on the repository
+	 *            configuration.
+	 */
+	public void setRefLogIdent(final PersonIdent pi) {
+		refLogIdent = pi;
+	}
+
+	/** @return the hook used while advertising the refs to the client */
+	public AdvertiseRefsHook getAdvertiseRefsHook() {
+		return advertiseRefsHook;
+	}
+
+	/** @return the filter used while advertising the refs to the client */
+	public RefFilter getRefFilter() {
+		return refFilter;
+	}
+
+	/**
+	 * Set the hook used while advertising the refs to the client.
+	 * <p>
+	 * If the {@link AdvertiseRefsHook} chooses to call
+	 * {@link #setAdvertisedRefs(Map,Set)}, only refs set by this hook
+	 * <em>and</em> selected by the {@link RefFilter} will be shown to the client.
+	 * Clients may still attempt to create or update a reference not advertised by
+	 * the configured {@link AdvertiseRefsHook}. These attempts should be rejected
+	 * by a matching {@link PreReceiveHook}.
+	 *
+	 * @param advertiseRefsHook
+	 *            the hook; may be null to show all refs.
+	 */
+	public void setAdvertiseRefsHook(final AdvertiseRefsHook advertiseRefsHook) {
+		if (advertiseRefsHook != null)
+			this.advertiseRefsHook = advertiseRefsHook;
+		else
+			this.advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
+	}
+
+	/**
+	 * Set the filter used while advertising the refs to the client.
+	 * <p>
+	 * Only refs allowed by this filter will be shown to the client.
+	 * The filter is run against the refs specified by the
+	 * {@link AdvertiseRefsHook} (if applicable).
+	 *
+	 * @param refFilter
+	 *            the filter; may be null to show all refs.
+	 */
+	public void setRefFilter(final RefFilter refFilter) {
+		this.refFilter = refFilter != null ? refFilter : RefFilter.DEFAULT;
+	}
+
+	/** @return timeout (in seconds) before aborting an IO operation. */
+	public int getTimeout() {
+		return timeout;
+	}
+
+	/**
+	 * Set the timeout before willing to abort an IO call.
+	 *
+	 * @param seconds
+	 *            number of seconds to wait (with no data transfer occurring)
+	 *            before aborting an IO read or write operation with the
+	 *            connected client.
+	 */
+	public void setTimeout(final int seconds) {
+		timeout = seconds;
+	}
+
+	/**
+	 * Set the maximum allowed Git object size.
+	 * <p>
+	 * If an object is larger than the given size the pack-parsing will throw an
+	 * exception aborting the receive-pack operation.
+	 *
+	 * @param limit
+	 *            the Git object size limit. If zero then there is not limit.
+	 */
+	public void setMaxObjectSizeLimit(final long limit) {
+		maxObjectSizeLimit = limit;
+	}
+
+	/**
+	 * Check whether the client expects a side-band stream.
+	 *
+	 * @return true if the client has advertised a side-band capability, false
+	 *     otherwise.
+	 * @throws RequestNotYetReadException
+	 *             if the client's request has not yet been read from the wire, so
+	 *             we do not know if they expect side-band. Note that the client
+	 *             may have already written the request, it just has not been
+	 *             read.
+	 */
+	public boolean isSideBand() throws RequestNotYetReadException {
+		if (enabledCapabilities == null)
+			throw new RequestNotYetReadException();
+		return enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K);
+	}
+
+	/** @return all of the command received by the current request. */
+	public List<ReceiveCommand> getAllCommands() {
+		return Collections.unmodifiableList(commands);
+	}
+
+	/**
+	 * Send an error message to the client.
+	 * <p>
+	 * If any error messages are sent before the references are advertised to
+	 * the client, the errors will be sent instead of the advertisement and the
+	 * receive operation will be aborted. All clients should receive and display
+	 * such early stage errors.
+	 * <p>
+	 * If the reference advertisements have already been sent, messages are sent
+	 * in a side channel. If the client doesn't support receiving messages, the
+	 * message will be discarded, with no other indication to the caller or to
+	 * the client.
+	 * <p>
+	 * {@link PreReceiveHook}s should always try to use
+	 * {@link ReceiveCommand#setResult(Result, String)} with a result status of
+	 * {@link Result#REJECTED_OTHER_REASON} to indicate any reasons for
+	 * rejecting an update. Messages attached to a command are much more likely
+	 * to be returned to the client.
+	 *
+	 * @param what
+	 *            string describing the problem identified by the hook. The
+	 *            string must not end with an LF, and must not contain an LF.
+	 */
+	public void sendError(final String what) {
+		if (refs == null) {
+			if (advertiseError == null)
+				advertiseError = new StringBuilder();
+			advertiseError.append(what).append('\n');
+		} else {
+			msgOutWrapper.write(Constants.encode("error: " + what + "\n"));
+		}
+	}
+
+	/**
+	 * Send a message to the client, if it supports receiving them.
+	 * <p>
+	 * If the client doesn't support receiving messages, the message will be
+	 * discarded, with no other indication to the caller or to the client.
+	 *
+	 * @param what
+	 *            string describing the problem identified by the hook. The
+	 *            string must not end with an LF, and must not contain an LF.
+	 */
+	public void sendMessage(final String what) {
+		msgOutWrapper.write(Constants.encode(what + "\n"));
+	}
+
+	/** @return an underlying stream for sending messages to the client. */
+	public OutputStream getMessageOutputStream() {
+		return msgOutWrapper;
+	}
+
+	/** @return true if any commands to be executed have been read. */
+	protected boolean hasCommands() {
+		return !commands.isEmpty();
+	}
+
+	/** @return true if an error occurred that should be advertised. */
+	protected boolean hasError() {
+		return advertiseError != null;
+	}
+
+	/**
+	 * Initialize the instance with the given streams.
+	 *
+	 * @param input
+	 *            raw input to read client commands and pack data from. Caller
+	 *            must ensure the input is buffered, otherwise read performance
+	 *            may suffer.
+	 * @param output
+	 *            response back to the Git network client. Caller must ensure
+	 *            the output is buffered, otherwise write performance may
+	 *            suffer.
+	 * @param messages
+	 *            secondary "notice" channel to send additional messages out
+	 *            through. When run over SSH this should be tied back to the
+	 *            standard error channel of the command execution. For most
+	 *            other network connections this should be null.
+	 */
+	protected void init(final InputStream input, final OutputStream output,
+			final OutputStream messages) {
+		origOut = output;
+		rawIn = input;
+		rawOut = output;
+		msgOut = messages;
+
+		if (timeout > 0) {
+			final Thread caller = Thread.currentThread();
+			timer = new InterruptTimer(caller.getName() + "-Timer");
+			timeoutIn = new TimeoutInputStream(rawIn, timer);
+			TimeoutOutputStream o = new TimeoutOutputStream(rawOut, timer);
+			timeoutIn.setTimeout(timeout * 1000);
+			o.setTimeout(timeout * 1000);
+			rawIn = timeoutIn;
+			rawOut = o;
+		}
+
+		pckIn = new PacketLineIn(rawIn);
+		pckOut = new PacketLineOut(rawOut);
+		pckOut.setFlushOnEnd(false);
+
+		enabledCapabilities = new HashSet<String>();
+		commands = new ArrayList<ReceiveCommand>();
+	}
+
+	/** @return advertised refs, or the default if not explicitly advertised. */
+	protected Map<String, Ref> getAdvertisedOrDefaultRefs() {
+		if (refs == null)
+			setAdvertisedRefs(null, null);
+		return refs;
+	}
+
+	/**
+	 * Receive a pack from the stream and check connectivity if necessary.
+	 *
+	 * @throws IOException
+	 *             an error occurred during unpacking or connectivity checking.
+	 */
+	protected void receivePackAndCheckConnectivity() throws IOException {
+		receivePack();
+		if (needCheckConnectivity())
+			checkConnectivity();
+		parser = null;
+	}
+
+	/**
+	 * Unlock the pack written by this object.
+	 *
+	 * @throws IOException
+	 *             the pack could not be unlocked.
+	 */
+	protected void unlockPack() throws IOException {
+		if (packLock != null) {
+			packLock.unlock();
+			packLock = null;
+		}
+	}
+
+	/**
+	 * Generate an advertisement of available refs and capabilities.
+	 *
+	 * @param adv
+	 *            the advertisement formatter.
+	 * @throws IOException
+	 *             the formatter failed to write an advertisement.
+	 * @throws ServiceMayNotContinueException
+	 *             the hook denied advertisement.
+	 */
+	public void sendAdvertisedRefs(final RefAdvertiser adv)
+			throws IOException, ServiceMayNotContinueException {
+		if (advertiseError != null) {
+			adv.writeOne("ERR " + advertiseError);
+			return;
+		}
+
+		try {
+			advertiseRefsHook.advertiseRefs(this);
+		} catch (ServiceMayNotContinueException fail) {
+			if (fail.getMessage() != null) {
+				adv.writeOne("ERR " + fail.getMessage());
+				fail.setOutput();
+			}
+			throw fail;
+		}
+
+		adv.init(db);
+		adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K);
+		adv.advertiseCapability(CAPABILITY_DELETE_REFS);
+		adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
+		if (allowOfsDelta)
+			adv.advertiseCapability(CAPABILITY_OFS_DELTA);
+		adv.send(getAdvertisedOrDefaultRefs());
+		for (ObjectId obj : advertisedHaves)
+			adv.advertiseHave(obj);
+		if (adv.isEmpty())
+			adv.advertiseId(ObjectId.zeroId(), "capabilities^{}");
+		adv.end();
+	}
+
+	/**
+	 * Receive a list of commands from the input.
+	 *
+	 * @throws IOException
+	 */
+	protected void recvCommands() throws IOException {
+		for (;;) {
+			String line;
+			try {
+				line = pckIn.readStringRaw();
+			} catch (EOFException eof) {
+				if (commands.isEmpty())
+					return;
+				throw eof;
+			}
+			if (line == PacketLineIn.END)
+				break;
+
+			if (commands.isEmpty()) {
+				final FirstLine firstLine = new FirstLine(line);
+				enabledCapabilities = firstLine.getCapabilities();
+				line = firstLine.getLine();
+			}
+
+			if (line.length() < 83) {
+				final String m = JGitText.get().errorInvalidProtocolWantedOldNewRef;
+				sendError(m);
+				throw new PackProtocolException(m);
+			}
+
+			final ObjectId oldId = ObjectId.fromString(line.substring(0, 40));
+			final ObjectId newId = ObjectId.fromString(line.substring(41, 81));
+			final String name = line.substring(82);
+			final ReceiveCommand cmd = new ReceiveCommand(oldId, newId, name);
+			if (name.equals(Constants.HEAD)) {
+				cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
+			} else {
+				cmd.setRef(refs.get(cmd.getRefName()));
+			}
+			commands.add(cmd);
+		}
+	}
+
+	/** Enable capabilities based on a previously read capabilities line. */
+	protected void enableCapabilities() {
+		reportStatus = enabledCapabilities.contains(CAPABILITY_REPORT_STATUS);
+
+		sideBand = enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K);
+		if (sideBand) {
+			OutputStream out = rawOut;
+
+			rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
+			msgOut = new SideBandOutputStream(CH_PROGRESS, MAX_BUF, out);
+
+			pckOut = new PacketLineOut(rawOut);
+			pckOut.setFlushOnEnd(false);
+		}
+	}
+
+	/** @return true if a pack is expected based on the list of commands. */
+	protected boolean needPack() {
+		for (final ReceiveCommand cmd : commands) {
+			if (cmd.getType() != ReceiveCommand.Type.DELETE)
+				return true;
+		}
+		return false;
+	}
+
+	/**
+	 * Receive a pack from the input and store it in the repository.
+	 *
+	 * @throws IOException
+	 *             an error occurred reading or indexing the pack.
+	 */
+	private void receivePack() throws IOException {
+		// It might take the client a while to pack the objects it needs
+		// to send to us.  We should increase our timeout so we don't
+		// abort while the client is computing.
+		//
+		if (timeoutIn != null)
+			timeoutIn.setTimeout(10 * timeout * 1000);
+
+		ProgressMonitor receiving = NullProgressMonitor.INSTANCE;
+		ProgressMonitor resolving = NullProgressMonitor.INSTANCE;
+		if (sideBand)
+			resolving = new SideBandProgressMonitor(msgOut);
+
+		ObjectInserter ins = db.newObjectInserter();
+		try {
+			String lockMsg = "jgit receive-pack";
+			if (getRefLogIdent() != null)
+				lockMsg += " from " + getRefLogIdent().toExternalString();
+
+			parser = ins.newPackParser(rawIn);
+			parser.setAllowThin(true);
+			parser.setNeedNewObjectIds(checkReferencedIsReachable);
+			parser.setNeedBaseObjectIds(checkReferencedIsReachable);
+			parser.setCheckEofAfterPackFooter(!biDirectionalPipe);
+			parser.setObjectChecking(isCheckReceivedObjects());
+			parser.setLockMessage(lockMsg);
+			parser.setMaxObjectSizeLimit(maxObjectSizeLimit);
+			packLock = parser.parse(receiving, resolving);
+			ins.flush();
+		} finally {
+			ins.release();
+		}
+
+		if (timeoutIn != null)
+			timeoutIn.setTimeout(timeout * 1000);
+	}
+
+	private boolean needCheckConnectivity() {
+		return isCheckReceivedObjects()
+				|| isCheckReferencedObjectsAreReachable();
+	}
+
+	private void checkConnectivity() throws IOException {
+		ObjectIdSubclassMap<ObjectId> baseObjects = null;
+		ObjectIdSubclassMap<ObjectId> providedObjects = null;
+
+		if (checkReferencedIsReachable) {
+			baseObjects = parser.getBaseObjectIds();
+			providedObjects = parser.getNewObjectIds();
+		}
+		parser = null;
+
+		final ObjectWalk ow = new ObjectWalk(db);
+		ow.setRetainBody(false);
+		if (checkReferencedIsReachable) {
+			ow.sort(RevSort.TOPO);
+			if (!baseObjects.isEmpty())
+				ow.sort(RevSort.BOUNDARY, true);
+		}
+
+		for (final ReceiveCommand cmd : commands) {
+			if (cmd.getResult() != Result.NOT_ATTEMPTED)
+				continue;
+			if (cmd.getType() == ReceiveCommand.Type.DELETE)
+				continue;
+			ow.markStart(ow.parseAny(cmd.getNewId()));
+		}
+		for (final ObjectId have : advertisedHaves) {
+			RevObject o = ow.parseAny(have);
+			ow.markUninteresting(o);
+
+			if (checkReferencedIsReachable && !baseObjects.isEmpty()) {
+				o = ow.peel(o);
+				if (o instanceof RevCommit)
+					o = ((RevCommit) o).getTree();
+				if (o instanceof RevTree)
+					ow.markUninteresting(o);
+			}
+		}
+
+		RevCommit c;
+		while ((c = ow.next()) != null) {
+			if (checkReferencedIsReachable //
+					&& !c.has(RevFlag.UNINTERESTING) //
+					&& !providedObjects.contains(c))
+				throw new MissingObjectException(c, Constants.TYPE_COMMIT);
+		}
+
+		RevObject o;
+		while ((o = ow.nextObject()) != null) {
+			if (o.has(RevFlag.UNINTERESTING))
+				continue;
+
+			if (checkReferencedIsReachable) {
+				if (providedObjects.contains(o))
+					continue;
+				else
+					throw new MissingObjectException(o, o.getType());
+			}
+
+			if (o instanceof RevBlob && !db.hasObject(o))
+				throw new MissingObjectException(o, Constants.TYPE_BLOB);
+		}
+
+		if (checkReferencedIsReachable) {
+			for (ObjectId id : baseObjects) {
+				o = ow.parseAny(id);
+				if (!o.has(RevFlag.UNINTERESTING))
+					throw new MissingObjectException(o, o.getType());
+			}
+		}
+	}
+
+	/** Validate the command list. */
+	protected void validateCommands() {
+		for (final ReceiveCommand cmd : commands) {
+			final Ref ref = cmd.getRef();
+			if (cmd.getResult() != Result.NOT_ATTEMPTED)
+				continue;
+
+			if (cmd.getType() == ReceiveCommand.Type.DELETE
+					&& !isAllowDeletes()) {
+				// Deletes are not supported on this repository.
+				//
+				cmd.setResult(Result.REJECTED_NODELETE);
+				continue;
+			}
+
+			if (cmd.getType() == ReceiveCommand.Type.CREATE) {
+				if (!isAllowCreates()) {
+					cmd.setResult(Result.REJECTED_NOCREATE);
+					continue;
+				}
+
+				if (ref != null && !isAllowNonFastForwards()) {
+					// Creation over an existing ref is certainly not going
+					// to be a fast-forward update. We can reject it early.
+					//
+					cmd.setResult(Result.REJECTED_NONFASTFORWARD);
+					continue;
+				}
+
+				if (ref != null) {
+					// A well behaved client shouldn't have sent us a
+					// create command for a ref we advertised to it.
+					//
+					cmd.setResult(Result.REJECTED_OTHER_REASON, MessageFormat
+							.format(JGitText.get().refAlreadyExists, ref));
+					continue;
+				}
+			}
+
+			if (cmd.getType() == ReceiveCommand.Type.DELETE && ref != null
+					&& !ObjectId.zeroId().equals(cmd.getOldId())
+					&& !ref.getObjectId().equals(cmd.getOldId())) {
+				// Delete commands can be sent with the old id matching our
+				// advertised value, *OR* with the old id being 0{40}. Any
+				// other requested old id is invalid.
+				//
+				cmd.setResult(Result.REJECTED_OTHER_REASON,
+						JGitText.get().invalidOldIdSent);
+				continue;
+			}
+
+			if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
+				if (ref == null) {
+					// The ref must have been advertised in order to be updated.
+					//
+					cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef);
+					continue;
+				}
+
+				if (!ref.getObjectId().equals(cmd.getOldId())) {
+					// A properly functioning client will send the same
+					// object id we advertised.
+					//
+					cmd.setResult(Result.REJECTED_OTHER_REASON,
+							JGitText.get().invalidOldIdSent);
+					continue;
+				}
+
+				// Is this possibly a non-fast-forward style update?
+				//
+				RevObject oldObj, newObj;
+				try {
+					oldObj = walk.parseAny(cmd.getOldId());
+				} catch (IOException e) {
+					cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
+							.getOldId().name());
+					continue;
+				}
+
+				try {
+					newObj = walk.parseAny(cmd.getNewId());
+				} catch (IOException e) {
+					cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
+							.getNewId().name());
+					continue;
+				}
+
+				if (oldObj instanceof RevCommit && newObj instanceof RevCommit) {
+					try {
+						if (!walk.isMergedInto((RevCommit) oldObj,
+								(RevCommit) newObj)) {
+							cmd
+									.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
+						}
+					} catch (MissingObjectException e) {
+						cmd.setResult(Result.REJECTED_MISSING_OBJECT, e
+								.getMessage());
+					} catch (IOException e) {
+						cmd.setResult(Result.REJECTED_OTHER_REASON);
+					}
+				} else {
+					cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
+				}
+			}
+
+			if (!cmd.getRefName().startsWith(Constants.R_REFS)
+					|| !Repository.isValidRefName(cmd.getRefName())) {
+				cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().funnyRefname);
+			}
+		}
+	}
+
+	/**
+	 * Filter the list of commands according to result.
+	 *
+	 * @param want
+	 *            desired status to filter by.
+	 * @return a copy of the command list containing only those commands with the
+	 *         desired status.
+	 */
+	protected List<ReceiveCommand> filterCommands(final Result want) {
+		return ReceiveCommand.filter(commands, want);
+	}
+
+	/** Execute commands to update references. */
+	protected void executeCommands() {
+		List<ReceiveCommand> toApply = ReceiveCommand.filter(commands,
+				Result.NOT_ATTEMPTED);
+		ProgressMonitor updating = NullProgressMonitor.INSTANCE;
+		if (sideBand) {
+			SideBandProgressMonitor pm = new SideBandProgressMonitor(msgOut);
+			pm.setDelayStart(250, TimeUnit.MILLISECONDS);
+			updating = pm;
+		}
+		updating.beginTask(JGitText.get().updatingReferences, toApply.size());
+		for (ReceiveCommand cmd : toApply) {
+			updating.update(1);
+			cmd.execute(this);
+		}
+		updating.endTask();
+	}
+
+	/**
+	 * Send a status report.
+	 *
+	 * @param forClient
+	 *            true if this report is for a Git client, false if it is for an
+	 *            end-user.
+	 * @param unpackError
+	 *            an error that occurred during unpacking, or {@code null}
+	 * @param out
+	 *            the reporter for sending the status strings.
+	 * @throws IOException
+	 *             an error occurred writing the status report.
+	 */
+	protected void sendStatusReport(final boolean forClient,
+			final Throwable unpackError, final Reporter out) throws IOException {
+		if (unpackError != null) {
+			out.sendString("unpack error " + unpackError.getMessage());
+			if (forClient) {
+				for (final ReceiveCommand cmd : commands) {
+					out.sendString("ng " + cmd.getRefName()
+							+ " n/a (unpacker error)");
+				}
+			}
+			return;
+		}
+
+		if (forClient)
+			out.sendString("unpack ok");
+		for (final ReceiveCommand cmd : commands) {
+			if (cmd.getResult() == Result.OK) {
+				if (forClient)
+					out.sendString("ok " + cmd.getRefName());
+				continue;
+			}
+
+			final StringBuilder r = new StringBuilder();
+			r.append("ng ");
+			r.append(cmd.getRefName());
+			r.append(" ");
+
+			switch (cmd.getResult()) {
+			case NOT_ATTEMPTED:
+				r.append("server bug; ref not processed");
+				break;
+
+			case REJECTED_NOCREATE:
+				r.append("creation prohibited");
+				break;
+
+			case REJECTED_NODELETE:
+				r.append("deletion prohibited");
+				break;
+
+			case REJECTED_NONFASTFORWARD:
+				r.append("non-fast forward");
+				break;
+
+			case REJECTED_CURRENT_BRANCH:
+				r.append("branch is currently checked out");
+				break;
+
+			case REJECTED_MISSING_OBJECT:
+				if (cmd.getMessage() == null)
+					r.append("missing object(s)");
+				else if (cmd.getMessage().length() == Constants.OBJECT_ID_STRING_LENGTH)
+					r.append("object " + cmd.getMessage() + " missing");
+				else
+					r.append(cmd.getMessage());
+				break;
+
+			case REJECTED_OTHER_REASON:
+				if (cmd.getMessage() == null)
+					r.append("unspecified reason");
+				else
+					r.append(cmd.getMessage());
+				break;
+
+			case LOCK_FAILURE:
+				r.append("failed to lock");
+				break;
+
+			case OK:
+				// We shouldn't have reached this case (see 'ok' case above).
+				continue;
+			}
+			out.sendString(r.toString());
+		}
+	}
+
+	/**
+	 * Close and flush (if necessary) the underlying streams.
+	 *
+	 * @throws IOException
+	 */
+	protected void close() throws IOException {
+		if (sideBand) {
+			// If we are using side band, we need to send a final
+			// flush-pkt to tell the remote peer the side band is
+			// complete and it should stop decoding. We need to
+			// use the original output stream as rawOut is now the
+			// side band data channel.
+			//
+			((SideBandOutputStream) msgOut).flushBuffer();
+			((SideBandOutputStream) rawOut).flushBuffer();
+
+			PacketLineOut plo = new PacketLineOut(origOut);
+			plo.setFlushOnEnd(false);
+			plo.end();
+		}
+
+		if (biDirectionalPipe) {
+			// If this was a native git connection, flush the pipe for
+			// the caller. For smart HTTP we don't do this flush and
+			// instead let the higher level HTTP servlet code do it.
+			//
+			if (!sideBand && msgOut != null)
+				msgOut.flush();
+			rawOut.flush();
+		}
+	}
+
+	/**
+	 * Release any resources used by this object.
+	 *
+	 * @throws IOException
+	 *             the pack could not be unlocked.
+	 */
+	protected void release() throws IOException {
+		walk.release();
+		unlockPack();
+		timeoutIn = null;
+		rawIn = null;
+		rawOut = null;
+		msgOut = null;
+		pckIn = null;
+		pckOut = null;
+		refs = null;
+		enabledCapabilities = null;
+		commands = null;
+		if (timer != null) {
+			try {
+				timer.terminate();
+			} finally {
+				timer = null;
+			}
+		}
+	}
+
+	/** Interface for reporting status messages. */
+	static abstract class Reporter {
+			abstract void sendString(String s) throws IOException;
+	}
+}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
index 44cf829..96814c8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceiveCommand.java
@@ -54,7 +54,7 @@
 import org.eclipse.jgit.lib.RefUpdate;
 
 /**
- * A command being processed by {@link ReceivePack}.
+ * A command being processed by {@link BaseReceivePack}.
  * <p>
  * This command instance roughly translates to the server side representation of
  * the {@link RemoteRefUpdate} created by the client.
@@ -158,7 +158,7 @@ public static List<ReceiveCommand> filter(List<ReceiveCommand> commands,
 	private String message;
 
 	/**
-	 * Create a new command for {@link ReceivePack}.
+	 * Create a new command for {@link BaseReceivePack}.
 	 *
 	 * @param oldId
 	 *            the old object id; must not be null. Use
@@ -184,7 +184,7 @@ public ReceiveCommand(final ObjectId oldId, final ObjectId newId,
 	}
 
 	/**
-	 * Create a new command for {@link ReceivePack}.
+	 * Create a new command for {@link BaseReceivePack}.
 	 *
 	 * @param oldId
 	 *            the old object id; must not be null. Use
@@ -273,7 +273,7 @@ public void setResult(final Result s, final String m) {
 	 *            receive-pack session.
 	 * @since 2.0
 	 */
-	public void execute(final ReceivePack rp) {
+	public void execute(final BaseReceivePack rp) {
 		try {
 			final RefUpdate ru = rp.getRepository().updateRef(getRefName());
 			ru.setRefLogIdent(rp.getRefLogIdent());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 126d74f..99e629a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -43,197 +43,26 @@
 
 package org.eclipse.jgit.transport;
 
-import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_DELETE_REFS;
-import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_OFS_DELTA;
-import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_REPORT_STATUS;
-import static org.eclipse.jgit.transport.BasePackPushConnection.CAPABILITY_SIDE_BAND_64K;
-import static org.eclipse.jgit.transport.SideBandOutputStream.CH_DATA;
-import static org.eclipse.jgit.transport.SideBandOutputStream.CH_PROGRESS;
-import static org.eclipse.jgit.transport.SideBandOutputStream.MAX_BUF;
-
-import java.io.EOFException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
-import org.eclipse.jgit.errors.MissingObjectException;
-import org.eclipse.jgit.errors.PackProtocolException;
 import org.eclipse.jgit.errors.UnpackException;
-import org.eclipse.jgit.internal.JGitText;
-import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Constants;
-import org.eclipse.jgit.lib.NullProgressMonitor;
-import org.eclipse.jgit.lib.ObjectId;
-import org.eclipse.jgit.lib.ObjectIdSubclassMap;
-import org.eclipse.jgit.lib.ObjectInserter;
-import org.eclipse.jgit.lib.PersonIdent;
-import org.eclipse.jgit.lib.ProgressMonitor;
-import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.Config.SectionParser;
-import org.eclipse.jgit.revwalk.ObjectWalk;
-import org.eclipse.jgit.revwalk.RevBlob;
-import org.eclipse.jgit.revwalk.RevCommit;
-import org.eclipse.jgit.revwalk.RevFlag;
-import org.eclipse.jgit.revwalk.RevObject;
-import org.eclipse.jgit.revwalk.RevSort;
-import org.eclipse.jgit.revwalk.RevTree;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.storage.file.PackLock;
 import org.eclipse.jgit.transport.ReceiveCommand.Result;
 import org.eclipse.jgit.transport.RefAdvertiser.PacketLineOutRefAdvertiser;
-import org.eclipse.jgit.util.io.InterruptTimer;
-import org.eclipse.jgit.util.io.TimeoutInputStream;
-import org.eclipse.jgit.util.io.TimeoutOutputStream;
 
 /**
  * Implements the server side of a push connection, receiving objects.
  */
-public class ReceivePack {
-	/** Data in the first line of a request, the line itself plus capabilities. */
-	public static class FirstLine {
-		private final String line;
-		private final Set<String> capabilities;
-
-		/**
-		 * Parse the first line of a receive-pack request.
-		 *
-		 * @param line
-		 *            line from the client.
-		 */
-		public FirstLine(String line) {
-			final HashSet<String> caps = new HashSet<String>();
-			final int nul = line.indexOf('\0');
-			if (nul >= 0) {
-				for (String c : line.substring(nul + 1).split(" "))
-					caps.add(c);
-				this.line = line.substring(0, nul);
-			} else
-				this.line = line;
-			this.capabilities = Collections.unmodifiableSet(caps);
-		}
-
-		/** @return non-capabilities part of the line. */
-		public String getLine() {
-			return line;
-		}
-
-		/** @return capabilities parsed from the line. */
-		public Set<String> getCapabilities() {
-			return capabilities;
-		}
-	}
-
-	/** Database we write the stored objects into. */
-	private final Repository db;
-
-	/** Revision traversal support over {@link #db}. */
-	private final RevWalk walk;
-
-	/**
-	 * Is the client connection a bi-directional socket or pipe?
-	 * <p>
-	 * If true, this class assumes it can perform multiple read and write cycles
-	 * with the client over the input and output streams. This matches the
-	 * functionality available with a standard TCP/IP connection, or a local
-	 * operating system or in-memory pipe.
-	 * <p>
-	 * If false, this class runs in a read everything then output results mode,
-	 * making it suitable for single round-trip systems RPCs such as HTTP.
-	 */
-	private boolean biDirectionalPipe = true;
-
-	/** Should an incoming transfer validate objects? */
-	private boolean checkReceivedObjects;
-
-	/** Should an incoming transfer permit create requests? */
-	private boolean allowCreates;
-
-	/** Should an incoming transfer permit delete requests? */
-	private boolean allowDeletes;
-
-	/** Should an incoming transfer permit non-fast-forward requests? */
-	private boolean allowNonFastForwards;
-
-	private boolean allowOfsDelta;
-
-	/** Identity to record action as within the reflog. */
-	private PersonIdent refLogIdent;
-
-	/** Hook used while advertising the refs to the client. */
-	private AdvertiseRefsHook advertiseRefsHook;
-
-	/** Filter used while advertising the refs to the client. */
-	private RefFilter refFilter;
-
+public class ReceivePack extends BaseReceivePack {
 	/** Hook to validate the update commands before execution. */
 	private PreReceiveHook preReceive;
 
 	/** Hook to report on the commands after execution. */
 	private PostReceiveHook postReceive;
 
-	/** Timeout in seconds to wait for client interaction. */
-	private int timeout;
-
-	/** Timer to manage {@link #timeout}. */
-	private InterruptTimer timer;
-
-	private TimeoutInputStream timeoutIn;
-
-	private InputStream rawIn;
-
-	private OutputStream rawOut;
-
-	private OutputStream msgOut;
-
-	private final MessageOutputWrapper msgOutWrapper = new MessageOutputWrapper();
-
-	private PacketLineIn pckIn;
-
-	private PacketLineOut pckOut;
-
-	private PackParser parser;
-
-	/** The refs we advertised as existing at the start of the connection. */
-	private Map<String, Ref> refs;
-
-	/** All SHA-1s shown to the client, which can be possible edges. */
-	private Set<ObjectId> advertisedHaves;
-
-	/** Capabilities requested by the client. */
-	private Set<String> enabledCapabilities;
-
-	/** Commands to execute, as received by the client. */
-	private List<ReceiveCommand> commands;
-
-	/** Error to display instead of advertising the references. */
-	private StringBuilder advertiseError;
-
-	/** An exception caught while unpacking and fsck'ing the objects. */
-	private Throwable unpackError;
-
-	/** If {@link BasePackPushConnection#CAPABILITY_REPORT_STATUS} is enabled. */
-	private boolean reportStatus;
-
-	/** If {@link BasePackPushConnection#CAPABILITY_SIDE_BAND_64K} is enabled. */
-	private boolean sideBand;
-
-	/** Lock around the received pack file, while updating refs. */
-	private PackLock packLock;
-
-	private boolean checkReferencedIsReachable;
-
-	/** Git object size limit */
-	private long maxObjectSizeLimit;
-
 	/**
 	 * Create a new pack receive for an open repository.
 	 *
@@ -241,341 +70,9 @@ public Set<String> getCapabilities() {
 	 *            the destination repository.
 	 */
 	public ReceivePack(final Repository into) {
-		db = into;
-		walk = new RevWalk(db);
-
-		final ReceiveConfig cfg = db.getConfig().get(ReceiveConfig.KEY);
-		checkReceivedObjects = cfg.checkReceivedObjects;
-		allowCreates = cfg.allowCreates;
-		allowDeletes = cfg.allowDeletes;
-		allowNonFastForwards = cfg.allowNonFastForwards;
-		allowOfsDelta = cfg.allowOfsDelta;
-		advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
-		refFilter = RefFilter.DEFAULT;
+		super(into);
 		preReceive = PreReceiveHook.NULL;
 		postReceive = PostReceiveHook.NULL;
-		advertisedHaves = new HashSet<ObjectId>();
-	}
-
-	private static class ReceiveConfig {
-		static final SectionParser<ReceiveConfig> KEY = new SectionParser<ReceiveConfig>() {
-			public ReceiveConfig parse(final Config cfg) {
-				return new ReceiveConfig(cfg);
-			}
-		};
-
-		final boolean checkReceivedObjects;
-
-		final boolean allowCreates;
-
-		final boolean allowDeletes;
-
-		final boolean allowNonFastForwards;
-
-		final boolean allowOfsDelta;
-
-		ReceiveConfig(final Config config) {
-			checkReceivedObjects = config.getBoolean("receive", "fsckobjects",
-					false);
-			allowCreates = true;
-			allowDeletes = !config.getBoolean("receive", "denydeletes", false);
-			allowNonFastForwards = !config.getBoolean("receive",
-					"denynonfastforwards", false);
-			allowOfsDelta = config.getBoolean("repack", "usedeltabaseoffset",
-					true);
-		}
-	}
-
-	/**
-	 * Output stream that wraps the current {@link #msgOut}.
-	 * <p>
-	 * We don't want to expose {@link #msgOut} directly because it can change
-	 * several times over the course of a session.
-	 */
-	private class MessageOutputWrapper extends OutputStream {
-		@Override
-		public void write(int ch) {
-			if (msgOut != null) {
-				try {
-					msgOut.write(ch);
-				} catch (IOException e) {
-					// Ignore write failures.
-				}
-			}
-		}
-
-		@Override
-		public void write(byte[] b, int off, int len) {
-			if (msgOut != null) {
-				try {
-					msgOut.write(b, off, len);
-				} catch (IOException e) {
-					// Ignore write failures.
-				}
-			}
-		}
-
-		@Override
-		public void write(byte[] b) {
-			write(b, 0, b.length);
-		}
-
-		@Override
-		public void flush() {
-			if (msgOut != null) {
-				try {
-					msgOut.flush();
-				} catch (IOException e) {
-					// Ignore write failures.
-				}
-			}
-		}
-	}
-
-	/** @return the repository this receive completes into. */
-	public final Repository getRepository() {
-		return db;
-	}
-
-	/** @return the RevWalk instance used by this connection. */
-	public final RevWalk getRevWalk() {
-		return walk;
-	}
-
-	/**
-	 * Get refs which were advertised to the client.
-	 *
-	 * @return all refs which were advertised to the client, or null if
-	 *         {@link #setAdvertisedRefs(Map, Set)} has not been called yet.
-	 */
-	public final Map<String, Ref> getAdvertisedRefs() {
-		return refs;
-	}
-
-	/**
-	 * Set the refs advertised by this ReceivePack.
-	 * <p>
-	 * Intended to be called from a {@link PreReceiveHook}.
-	 *
-	 * @param allRefs
-	 *            explicit set of references to claim as advertised by this
-	 *            ReceivePack instance. This overrides any references that
-	 *            may exist in the source repository. The map is passed
-	 *            to the configured {@link #getRefFilter()}. If null, assumes
-	 *            all refs were advertised.
-	 * @param additionalHaves
-	 *            explicit set of additional haves to claim as advertised. If
-	 *            null, assumes the default set of additional haves from the
-	 *            repository.
-	 */
-	public void setAdvertisedRefs(Map<String, Ref> allRefs,
-			Set<ObjectId> additionalHaves) {
-		refs = allRefs != null ? allRefs : db.getAllRefs();
-		refs = refFilter.filter(refs);
-
-		Ref head = refs.get(Constants.HEAD);
-		if (head != null && head.isSymbolic())
-			refs.remove(Constants.HEAD);
-
-		for (Ref ref : refs.values()) {
-			if (ref.getObjectId() != null)
-				advertisedHaves.add(ref.getObjectId());
-		}
-		if (additionalHaves != null)
-			advertisedHaves.addAll(additionalHaves);
-		else
-			advertisedHaves.addAll(db.getAdditionalHaves());
-	}
-
-	/**
-	 * Get objects advertised to the client.
-	 *
-	 * @return the set of objects advertised to the as present in this repository,
-	 *         or null if {@link #setAdvertisedRefs(Map, Set)} has not been called
-	 *         yet.
-	 */
-	public final Set<ObjectId> getAdvertisedObjects() {
-		return advertisedHaves;
-	}
-
-	/**
-	 * @return true if this instance will validate all referenced, but not
-	 *         supplied by the client, objects are reachable from another
-	 *         reference.
-	 */
-	public boolean isCheckReferencedObjectsAreReachable() {
-		return checkReferencedIsReachable;
-	}
-
-	/**
-	 * Validate all referenced but not supplied objects are reachable.
-	 * <p>
-	 * If enabled, this instance will verify that references to objects not
-	 * contained within the received pack are already reachable through at least
-	 * one other reference displayed as part of {@link #getAdvertisedRefs()}.
-	 * <p>
-	 * This feature is useful when the application doesn't trust the client to
-	 * not provide a forged SHA-1 reference to an object, in an attempt to
-	 * access parts of the DAG that they aren't allowed to see and which have
-	 * been hidden from them via the configured {@link AdvertiseRefsHook} or
-	 * {@link RefFilter}.
-	 * <p>
-	 * Enabling this feature may imply at least some, if not all, of the same
-	 * functionality performed by {@link #setCheckReceivedObjects(boolean)}.
-	 * Applications are encouraged to enable both features, if desired.
-	 *
-	 * @param b
-	 *            {@code true} to enable the additional check.
-	 */
-	public void setCheckReferencedObjectsAreReachable(boolean b) {
-		this.checkReferencedIsReachable = b;
-	}
-
-	/**
-	 * @return true if this class expects a bi-directional pipe opened between
-	 *         the client and itself. The default is true.
-	 */
-	public boolean isBiDirectionalPipe() {
-		return biDirectionalPipe;
-	}
-
-	/**
-	 * @param twoWay
-	 *            if true, this class will assume the socket is a fully
-	 *            bidirectional pipe between the two peers and takes advantage
-	 *            of that by first transmitting the known refs, then waiting to
-	 *            read commands. If false, this class assumes it must read the
-	 *            commands before writing output and does not perform the
-	 *            initial advertising.
-	 */
-	public void setBiDirectionalPipe(final boolean twoWay) {
-		biDirectionalPipe = twoWay;
-	}
-
-	/**
-	 * @return true if this instance will verify received objects are formatted
-	 *         correctly. Validating objects requires more CPU time on this side
-	 *         of the connection.
-	 */
-	public boolean isCheckReceivedObjects() {
-		return checkReceivedObjects;
-	}
-
-	/**
-	 * @param check
-	 *            true to enable checking received objects; false to assume all
-	 *            received objects are valid.
-	 */
-	public void setCheckReceivedObjects(final boolean check) {
-		checkReceivedObjects = check;
-	}
-
-	/** @return true if the client can request refs to be created. */
-	public boolean isAllowCreates() {
-		return allowCreates;
-	}
-
-	/**
-	 * @param canCreate
-	 *            true to permit create ref commands to be processed.
-	 */
-	public void setAllowCreates(final boolean canCreate) {
-		allowCreates = canCreate;
-	}
-
-	/** @return true if the client can request refs to be deleted. */
-	public boolean isAllowDeletes() {
-		return allowDeletes;
-	}
-
-	/**
-	 * @param canDelete
-	 *            true to permit delete ref commands to be processed.
-	 */
-	public void setAllowDeletes(final boolean canDelete) {
-		allowDeletes = canDelete;
-	}
-
-	/**
-	 * @return true if the client can request non-fast-forward updates of a ref,
-	 *         possibly making objects unreachable.
-	 */
-	public boolean isAllowNonFastForwards() {
-		return allowNonFastForwards;
-	}
-
-	/**
-	 * @param canRewind
-	 *            true to permit the client to ask for non-fast-forward updates
-	 *            of an existing ref.
-	 */
-	public void setAllowNonFastForwards(final boolean canRewind) {
-		allowNonFastForwards = canRewind;
-	}
-
-	/** @return identity of the user making the changes in the reflog. */
-	public PersonIdent getRefLogIdent() {
-		return refLogIdent;
-	}
-
-	/**
-	 * Set the identity of the user appearing in the affected reflogs.
-	 * <p>
-	 * The timestamp portion of the identity is ignored. A new identity with the
-	 * current timestamp will be created automatically when the updates occur
-	 * and the log records are written.
-	 *
-	 * @param pi
-	 *            identity of the user. If null the identity will be
-	 *            automatically determined based on the repository
-	 *            configuration.
-	 */
-	public void setRefLogIdent(final PersonIdent pi) {
-		refLogIdent = pi;
-	}
-
-	/** @return the hook used while advertising the refs to the client */
-	public AdvertiseRefsHook getAdvertiseRefsHook() {
-		return advertiseRefsHook;
-	}
-
-	/** @return the filter used while advertising the refs to the client */
-	public RefFilter getRefFilter() {
-		return refFilter;
-	}
-
-	/**
-	 * Set the hook used while advertising the refs to the client.
-	 * <p>
-	 * If the {@link AdvertiseRefsHook} chooses to call
-	 * {@link #setAdvertisedRefs(Map,Set)}, only refs set by this hook
-	 * <em>and</em> selected by the {@link RefFilter} will be shown to the client.
-	 * Clients may still attempt to create or update a reference not advertised by
-	 * the configured {@link AdvertiseRefsHook}. These attempts should be rejected
-	 * by a matching {@link PreReceiveHook}.
-	 *
-	 * @param advertiseRefsHook
-	 *            the hook; may be null to show all refs.
-	 */
-	public void setAdvertiseRefsHook(final AdvertiseRefsHook advertiseRefsHook) {
-		if (advertiseRefsHook != null)
-			this.advertiseRefsHook = advertiseRefsHook;
-		else
-			this.advertiseRefsHook = AdvertiseRefsHook.DEFAULT;
-	}
-
-	/**
-	 * Set the filter used while advertising the refs to the client.
-	 * <p>
-	 * Only refs allowed by this filter will be shown to the client.
-	 * The filter is run against the refs specified by the
-	 * {@link AdvertiseRefsHook} (if applicable).
-	 *
-	 * @param refFilter
-	 *            the filter; may be null to show all refs.
-	 */
-	public void setRefFilter(final RefFilter refFilter) {
-		this.refFilter = refFilter != null ? refFilter : RefFilter.DEFAULT;
 	}
 
 	/** @return the hook invoked before updates occur. */
@@ -620,110 +117,6 @@ public void setPostReceiveHook(final PostReceiveHook h) {
 		postReceive = h != null ? h : PostReceiveHook.NULL;
 	}
 
-	/** @return timeout (in seconds) before aborting an IO operation. */
-	public int getTimeout() {
-		return timeout;
-	}
-
-	/**
-	 * Set the timeout before willing to abort an IO call.
-	 *
-	 * @param seconds
-	 *            number of seconds to wait (with no data transfer occurring)
-	 *            before aborting an IO read or write operation with the
-	 *            connected client.
-	 */
-	public void setTimeout(final int seconds) {
-		timeout = seconds;
-	}
-
-	/**
-	 * Set the maximum allowed Git object size.
-	 * <p>
-	 * If an object is larger than the given size the pack-parsing will throw an
-	 * exception aborting the receive-pack operation.
-	 *
-	 * @param limit
-	 *            the Git object size limit. If zero then there is not limit.
-	 */
-	public void setMaxObjectSizeLimit(final long limit) {
-		maxObjectSizeLimit = limit;
-	}
-
-	/**
-	 * Check whether the client expects a side-band stream.
-	 *
-	 * @return true if the client has advertised a side-band capability, false
-	 *     otherwise.
-	 * @throws RequestNotYetReadException
-	 *             if the client's request has not yet been read from the wire, so
-	 *             we do not know if they expect side-band. Note that the client
-	 *             may have already written the request, it just has not been
-	 *             read.
-	 */
-	public boolean isSideBand() throws RequestNotYetReadException {
-		if (enabledCapabilities == null)
-			throw new RequestNotYetReadException();
-		return enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K);
-	}
-
-	/** @return all of the command received by the current request. */
-	public List<ReceiveCommand> getAllCommands() {
-		return Collections.unmodifiableList(commands);
-	}
-
-	/**
-	 * Send an error message to the client.
-	 * <p>
-	 * If any error messages are sent before the references are advertised to
-	 * the client, the errors will be sent instead of the advertisement and the
-	 * receive operation will be aborted. All clients should receive and display
-	 * such early stage errors.
-	 * <p>
-	 * If the reference advertisements have already been sent, messages are sent
-	 * in a side channel. If the client doesn't support receiving messages, the
-	 * message will be discarded, with no other indication to the caller or to
-	 * the client.
-	 * <p>
-	 * {@link PreReceiveHook}s should always try to use
-	 * {@link ReceiveCommand#setResult(Result, String)} with a result status of
-	 * {@link Result#REJECTED_OTHER_REASON} to indicate any reasons for
-	 * rejecting an update. Messages attached to a command are much more likely
-	 * to be returned to the client.
-	 *
-	 * @param what
-	 *            string describing the problem identified by the hook. The
-	 *            string must not end with an LF, and must not contain an LF.
-	 */
-	public void sendError(final String what) {
-		if (refs == null) {
-			if (advertiseError == null)
-				advertiseError = new StringBuilder();
-			advertiseError.append(what).append('\n');
-		} else {
-			msgOutWrapper.write(Constants.encode("error: " + what + "\n"));
-		}
-	}
-
-	/**
-	 * Send a message to the client, if it supports receiving them.
-	 * <p>
-	 * If the client doesn't support receiving messages, the message will be
-	 * discarded, with no other indication to the caller or to the client.
-	 *
-	 * @param what
-	 *            string describing the problem identified by the hook. The
-	 *            string must not end with an LF, and must not contain an LF.
-	 */
-	public void sendMessage(final String what) {
-		msgOutWrapper.write(Constants.encode(what + "\n"));
-	}
-
-	/** @return an underlying stream for sending messages to the client. */
-	public OutputStream getMessageOutputStream() {
-		return msgOutWrapper;
-	}
-
 	/**
 	 * Execute the receive task on the socket.
 	 *
@@ -744,103 +137,34 @@ public OutputStream getMessageOutputStream() {
 	 */
 	public void receive(final InputStream input, final OutputStream output,
 			final OutputStream messages) throws IOException {
+		init(input, output, messages);
 		try {
-			rawIn = input;
-			rawOut = output;
-			msgOut = messages;
-
-			if (timeout > 0) {
-				final Thread caller = Thread.currentThread();
-				timer = new InterruptTimer(caller.getName() + "-Timer");
-				timeoutIn = new TimeoutInputStream(rawIn, timer);
-				TimeoutOutputStream o = new TimeoutOutputStream(rawOut, timer);
-				timeoutIn.setTimeout(timeout * 1000);
-				o.setTimeout(timeout * 1000);
-				rawIn = timeoutIn;
-				rawOut = o;
-			}
-
-			pckIn = new PacketLineIn(rawIn);
-			pckOut = new PacketLineOut(rawOut);
-			pckOut.setFlushOnEnd(false);
-
-			commands = new ArrayList<ReceiveCommand>();
-
 			service();
 		} finally {
-			walk.release();
 			try {
-				if (sideBand) {
-					// If we are using side band, we need to send a final
-					// flush-pkt to tell the remote peer the side band is
-					// complete and it should stop decoding. We need to
-					// use the original output stream as rawOut is now the
-					// side band data channel.
-					//
-					((SideBandOutputStream) msgOut).flushBuffer();
-					((SideBandOutputStream) rawOut).flushBuffer();
-
-					PacketLineOut plo = new PacketLineOut(output);
-					plo.setFlushOnEnd(false);
-					plo.end();
-				}
-
-				if (biDirectionalPipe) {
-					// If this was a native git connection, flush the pipe for
-					// the caller. For smart HTTP we don't do this flush and
-					// instead let the higher level HTTP servlet code do it.
-					//
-					if (!sideBand && msgOut != null)
-						msgOut.flush();
-					rawOut.flush();
-				}
+				close();
 			} finally {
-				unlockPack();
-				timeoutIn = null;
-				rawIn = null;
-				rawOut = null;
-				msgOut = null;
-				pckIn = null;
-				pckOut = null;
-				refs = null;
-				enabledCapabilities = null;
-				commands = null;
-				if (timer != null) {
-					try {
-						timer.terminate();
-					} finally {
-						timer = null;
-					}
-				}
+				release();
 			}
 		}
 	}
 
-	private Map<String, Ref> getAdvertisedOrDefaultRefs() {
-		if (refs == null)
-			setAdvertisedRefs(null, null);
-		return refs;
-	}
-
 	private void service() throws IOException {
 		if (biDirectionalPipe) {
 			sendAdvertisedRefs(new PacketLineOutRefAdvertiser(pckOut));
 			pckOut.flush();
 		} else
 			getAdvertisedOrDefaultRefs();
-		if (advertiseError != null)
+		if (hasError())
 			return;
 		recvCommands();
-		if (!commands.isEmpty()) {
+		if (hasCommands()) {
 			enableCapabilities();
 
+			Throwable unpackError = null;
 			if (needPack()) {
 				try {
-					receivePack();
-					if (needCheckConnectivity())
-						checkConnectivity();
-					parser = null;
-					unpackError = null;
+					receivePackAndCheckConnectivity();
 				} catch (IOException err) {
 					unpackError = err;
 				} catch (RuntimeException err) {
@@ -852,463 +176,35 @@ private void service() throws IOException {
 
 			if (unpackError == null) {
 				validateCommands();
+				preReceive.onPreReceive(this, filterCommands(Result.NOT_ATTEMPTED));
 				executeCommands();
 			}
 			unlockPack();
 
 			if (reportStatus) {
-				sendStatusReport(true, new Reporter() {
+				sendStatusReport(true, unpackError, new Reporter() {
 					void sendString(final String s) throws IOException {
 						pckOut.writeString(s + "\n");
 					}
 				});
 				pckOut.end();
 			} else if (msgOut != null) {
-				sendStatusReport(false, new Reporter() {
+				sendStatusReport(false, unpackError, new Reporter() {
 					void sendString(final String s) throws IOException {
 						msgOut.write(Constants.encode(s + "\n"));
 					}
 				});
 			}
 
-			postReceive.onPostReceive(this,
-					ReceiveCommand.filter(commands, Result.OK));
+			postReceive.onPostReceive(this, filterCommands(Result.OK));
 
 			if (unpackError != null)
 				throw new UnpackException(unpackError);
 		}
 	}
 
-	private void unlockPack() throws IOException {
-		if (packLock != null) {
-			packLock.unlock();
-			packLock = null;
-		}
-	}
-
-	/**
-	 * Generate an advertisement of available refs and capabilities.
-	 *
-	 * @param adv
-	 *            the advertisement formatter.
-	 * @throws IOException
-	 *             the formatter failed to write an advertisement.
-	 * @throws ServiceMayNotContinueException
-	 *             the hook denied advertisement.
-	 */
-	public void sendAdvertisedRefs(final RefAdvertiser adv) throws IOException,
-			 ServiceMayNotContinueException {
-		if (advertiseError != null) {
-			adv.writeOne("ERR " + advertiseError);
-			return;
-		}
-
-		try {
-			advertiseRefsHook.advertiseRefs(this);
-		} catch (ServiceMayNotContinueException fail) {
-			if (fail.getMessage() != null) {
-				adv.writeOne("ERR " + fail.getMessage());
-				fail.setOutput();
-			}
-			throw fail;
-		}
-
-		adv.init(db);
-		adv.advertiseCapability(CAPABILITY_SIDE_BAND_64K);
-		adv.advertiseCapability(CAPABILITY_DELETE_REFS);
-		adv.advertiseCapability(CAPABILITY_REPORT_STATUS);
-		if (allowOfsDelta)
-			adv.advertiseCapability(CAPABILITY_OFS_DELTA);
-		adv.send(getAdvertisedOrDefaultRefs());
-		for (ObjectId obj : advertisedHaves)
-			adv.advertiseHave(obj);
-		if (adv.isEmpty())
-			adv.advertiseId(ObjectId.zeroId(), "capabilities^{}");
-		adv.end();
-	}
-
-	private void recvCommands() throws IOException {
-		for (;;) {
-			String line;
-			try {
-				line = pckIn.readStringRaw();
-			} catch (EOFException eof) {
-				if (commands.isEmpty())
-					return;
-				throw eof;
-			}
-			if (line == PacketLineIn.END)
-				break;
-
-			if (commands.isEmpty()) {
-				final FirstLine firstLine = new FirstLine(line);
-				enabledCapabilities = firstLine.getCapabilities();
-				line = firstLine.getLine();
-			}
-
-			if (line.length() < 83) {
-				final String m = JGitText.get().errorInvalidProtocolWantedOldNewRef;
-				sendError(m);
-				throw new PackProtocolException(m);
-			}
-
-			final ObjectId oldId = ObjectId.fromString(line.substring(0, 40));
-			final ObjectId newId = ObjectId.fromString(line.substring(41, 81));
-			final String name = line.substring(82);
-			final ReceiveCommand cmd = new ReceiveCommand(oldId, newId, name);
-			if (name.equals(Constants.HEAD)) {
-				cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
-			} else {
-				cmd.setRef(refs.get(cmd.getRefName()));
-			}
-			commands.add(cmd);
-		}
-	}
-
-	private void enableCapabilities() {
-		reportStatus = enabledCapabilities.contains(CAPABILITY_REPORT_STATUS);
-
-		sideBand = enabledCapabilities.contains(CAPABILITY_SIDE_BAND_64K);
-		if (sideBand) {
-			OutputStream out = rawOut;
-
-			rawOut = new SideBandOutputStream(CH_DATA, MAX_BUF, out);
-			msgOut = new SideBandOutputStream(CH_PROGRESS, MAX_BUF, out);
-
-			pckOut = new PacketLineOut(rawOut);
-			pckOut.setFlushOnEnd(false);
-		}
-	}
-
-	private boolean needPack() {
-		for (final ReceiveCommand cmd : commands) {
-			if (cmd.getType() != ReceiveCommand.Type.DELETE)
-				return true;
-		}
-		return false;
-	}
-
-	private void receivePack() throws IOException {
-		// It might take the client a while to pack the objects it needs
-		// to send to us.  We should increase our timeout so we don't
-		// abort while the client is computing.
-		//
-		if (timeoutIn != null)
-			timeoutIn.setTimeout(10 * timeout * 1000);
-
-		ProgressMonitor receiving = NullProgressMonitor.INSTANCE;
-		ProgressMonitor resolving = NullProgressMonitor.INSTANCE;
-		if (sideBand)
-			resolving = new SideBandProgressMonitor(msgOut);
-
-		ObjectInserter ins = db.newObjectInserter();
-		try {
-			String lockMsg = "jgit receive-pack";
-			if (getRefLogIdent() != null)
-				lockMsg += " from " + getRefLogIdent().toExternalString();
-
-			parser = ins.newPackParser(rawIn);
-			parser.setAllowThin(true);
-			parser.setNeedNewObjectIds(checkReferencedIsReachable);
-			parser.setNeedBaseObjectIds(checkReferencedIsReachable);
-			parser.setCheckEofAfterPackFooter(!biDirectionalPipe);
-			parser.setObjectChecking(isCheckReceivedObjects());
-			parser.setLockMessage(lockMsg);
-			parser.setMaxObjectSizeLimit(maxObjectSizeLimit);
-			packLock = parser.parse(receiving, resolving);
-			ins.flush();
-		} finally {
-			ins.release();
-		}
-
-		if (timeoutIn != null)
-			timeoutIn.setTimeout(timeout * 1000);
-	}
-
-	private boolean needCheckConnectivity() {
-		return isCheckReceivedObjects()
-				|| isCheckReferencedObjectsAreReachable();
-	}
-
-	private void checkConnectivity() throws IOException {
-		ObjectIdSubclassMap<ObjectId> baseObjects = null;
-		ObjectIdSubclassMap<ObjectId> providedObjects = null;
-
-		if (checkReferencedIsReachable) {
-			baseObjects = parser.getBaseObjectIds();
-			providedObjects = parser.getNewObjectIds();
-		}
-		parser = null;
-
-		final ObjectWalk ow = new ObjectWalk(db);
-		ow.setRetainBody(false);
-		if (checkReferencedIsReachable) {
-			ow.sort(RevSort.TOPO);
-			if (!baseObjects.isEmpty())
-				ow.sort(RevSort.BOUNDARY, true);
-		}
-
-		for (final ReceiveCommand cmd : commands) {
-			if (cmd.getResult() != Result.NOT_ATTEMPTED)
-				continue;
-			if (cmd.getType() == ReceiveCommand.Type.DELETE)
-				continue;
-			ow.markStart(ow.parseAny(cmd.getNewId()));
-		}
-		for (final ObjectId have : advertisedHaves) {
-			RevObject o = ow.parseAny(have);
-			ow.markUninteresting(o);
-
-			if (checkReferencedIsReachable && !baseObjects.isEmpty()) {
-				o = ow.peel(o);
-				if (o instanceof RevCommit)
-					o = ((RevCommit) o).getTree();
-				if (o instanceof RevTree)
-					ow.markUninteresting(o);
-			}
-		}
-
-		RevCommit c;
-		while ((c = ow.next()) != null) {
-			if (checkReferencedIsReachable //
-					&& !c.has(RevFlag.UNINTERESTING) //
-					&& !providedObjects.contains(c))
-				throw new MissingObjectException(c, Constants.TYPE_COMMIT);
-		}
-
-		RevObject o;
-		while ((o = ow.nextObject()) != null) {
-			if (o.has(RevFlag.UNINTERESTING))
-				continue;
-
-			if (checkReferencedIsReachable) {
-				if (providedObjects.contains(o))
-					continue;
-				else
-					throw new MissingObjectException(o, o.getType());
-			}
-
-			if (o instanceof RevBlob && !db.hasObject(o))
-				throw new MissingObjectException(o, Constants.TYPE_BLOB);
-		}
-
-		if (checkReferencedIsReachable) {
-			for (ObjectId id : baseObjects) {
-				o = ow.parseAny(id);
-				if (!o.has(RevFlag.UNINTERESTING))
-					throw new MissingObjectException(o, o.getType());
-			}
-		}
-	}
-
-	private void validateCommands() {
-		for (final ReceiveCommand cmd : commands) {
-			final Ref ref = cmd.getRef();
-			if (cmd.getResult() != Result.NOT_ATTEMPTED)
-				continue;
-
-			if (cmd.getType() == ReceiveCommand.Type.DELETE
-					&& !isAllowDeletes()) {
-				// Deletes are not supported on this repository.
-				//
-				cmd.setResult(Result.REJECTED_NODELETE);
-				continue;
-			}
-
-			if (cmd.getType() == ReceiveCommand.Type.CREATE) {
-				if (!isAllowCreates()) {
-					cmd.setResult(Result.REJECTED_NOCREATE);
-					continue;
-				}
-
-				if (ref != null && !isAllowNonFastForwards()) {
-					// Creation over an existing ref is certainly not going
-					// to be a fast-forward update. We can reject it early.
-					//
-					cmd.setResult(Result.REJECTED_NONFASTFORWARD);
-					continue;
-				}
-
-				if (ref != null) {
-					// A well behaved client shouldn't have sent us a
-					// create command for a ref we advertised to it.
-					//
-					cmd.setResult(Result.REJECTED_OTHER_REASON, MessageFormat
-							.format(JGitText.get().refAlreadyExists, ref));
-					continue;
-				}
-			}
-
-			if (cmd.getType() == ReceiveCommand.Type.DELETE && ref != null
-					&& !ObjectId.zeroId().equals(cmd.getOldId())
-					&& !ref.getObjectId().equals(cmd.getOldId())) {
-				// Delete commands can be sent with the old id matching our
-				// advertised value, *OR* with the old id being 0{40}. Any
-				// other requested old id is invalid.
-				//
-				cmd.setResult(Result.REJECTED_OTHER_REASON,
-						JGitText.get().invalidOldIdSent);
-				continue;
-			}
-
-			if (cmd.getType() == ReceiveCommand.Type.UPDATE) {
-				if (ref == null) {
-					// The ref must have been advertised in order to be updated.
-					//
-					cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().noSuchRef);
-					continue;
-				}
-
-				if (!ref.getObjectId().equals(cmd.getOldId())) {
-					// A properly functioning client will send the same
-					// object id we advertised.
-					//
-					cmd.setResult(Result.REJECTED_OTHER_REASON,
-							JGitText.get().invalidOldIdSent);
-					continue;
-				}
-
-				// Is this possibly a non-fast-forward style update?
-				//
-				RevObject oldObj, newObj;
-				try {
-					oldObj = walk.parseAny(cmd.getOldId());
-				} catch (IOException e) {
-					cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
-							.getOldId().name());
-					continue;
-				}
-
-				try {
-					newObj = walk.parseAny(cmd.getNewId());
-				} catch (IOException e) {
-					cmd.setResult(Result.REJECTED_MISSING_OBJECT, cmd
-							.getNewId().name());
-					continue;
-				}
-
-				if (oldObj instanceof RevCommit && newObj instanceof RevCommit) {
-					try {
-						if (!walk.isMergedInto((RevCommit) oldObj,
-								(RevCommit) newObj)) {
-							cmd
-									.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
-						}
-					} catch (MissingObjectException e) {
-						cmd.setResult(Result.REJECTED_MISSING_OBJECT, e
-								.getMessage());
-					} catch (IOException e) {
-						cmd.setResult(Result.REJECTED_OTHER_REASON);
-					}
-				} else {
-					cmd.setType(ReceiveCommand.Type.UPDATE_NONFASTFORWARD);
-				}
-			}
-
-			if (!cmd.getRefName().startsWith(Constants.R_REFS)
-					|| !Repository.isValidRefName(cmd.getRefName())) {
-				cmd.setResult(Result.REJECTED_OTHER_REASON, JGitText.get().funnyRefname);
-			}
-		}
-	}
-
-	private void executeCommands() {
-		preReceive.onPreReceive(this,
-				ReceiveCommand.filter(commands, Result.NOT_ATTEMPTED));
-
-		List<ReceiveCommand> toApply = ReceiveCommand.filter(commands,
-				Result.NOT_ATTEMPTED);
-		ProgressMonitor updating = NullProgressMonitor.INSTANCE;
-		if (sideBand) {
-			SideBandProgressMonitor pm = new SideBandProgressMonitor(msgOut);
-			pm.setDelayStart(250, TimeUnit.MILLISECONDS);
-			updating = pm;
-		}
-		updating.beginTask(JGitText.get().updatingReferences, toApply.size());
-		for (ReceiveCommand cmd : toApply) {
-			updating.update(1);
-			cmd.execute(this);
-		}
-		updating.endTask();
-	}
-
-	private void sendStatusReport(final boolean forClient, final Reporter out)
-			throws IOException {
-		if (unpackError != null) {
-			out.sendString("unpack error " + unpackError.getMessage());
-			if (forClient) {
-				for (final ReceiveCommand cmd : commands) {
-					out.sendString("ng " + cmd.getRefName()
-							+ " n/a (unpacker error)");
-				}
-			}
-			return;
-		}
-
-		if (forClient)
-			out.sendString("unpack ok");
-		for (final ReceiveCommand cmd : commands) {
-			if (cmd.getResult() == Result.OK) {
-				if (forClient)
-					out.sendString("ok " + cmd.getRefName());
-				continue;
-			}
-
-			final StringBuilder r = new StringBuilder();
-			r.append("ng ");
-			r.append(cmd.getRefName());
-			r.append(" ");
-
-			switch (cmd.getResult()) {
-			case NOT_ATTEMPTED:
-				r.append("server bug; ref not processed");
-				break;
-
-			case REJECTED_NOCREATE:
-				r.append("creation prohibited");
-				break;
-
-			case REJECTED_NODELETE:
-				r.append("deletion prohibited");
-				break;
-
-			case REJECTED_NONFASTFORWARD:
-				r.append("non-fast forward");
-				break;
-
-			case REJECTED_CURRENT_BRANCH:
-				r.append("branch is currently checked out");
-				break;
-
-			case REJECTED_MISSING_OBJECT:
-				if (cmd.getMessage() == null)
-					r.append("missing object(s)");
-				else if (cmd.getMessage().length() == Constants.OBJECT_ID_STRING_LENGTH)
-					r.append("object " + cmd.getMessage() + " missing");
-				else
-					r.append(cmd.getMessage());
-				break;
-
-			case REJECTED_OTHER_REASON:
-				if (cmd.getMessage() == null)
-					r.append("unspecified reason");
-				else
-					r.append(cmd.getMessage());
-				break;
-
-			case LOCK_FAILURE:
-				r.append("failed to lock");
-				break;
-
-			case OK:
-				// We shouldn't have reached this case (see 'ok' case above).
-				continue;
-			}
-			out.sendString(r.toString());
-		}
-	}
-
-	static abstract class Reporter {
-		abstract void sendString(String s) throws IOException;
+	@Override
+	protected String getLockMessageProcessName() {
+		return "jgit receive-pack";
 	}
 }
