 		cb: type: "function"
 	bindings.initRepository path, bare, wrapCallback cb, (repo) ->
 		cb null, new Repository repo
-
 Gitteh.clone = =>
 	[url, path, cb] = args
 		url: type: "string"

	immutable(@, {fetchSpec, pushSpec})
		.set("fetchSpec")
		.set("pushSpec")

	@connect = =>
		[dir, cb] = args
			dir: type: "remoteDir"
			cb: type: "function"
		dir = if dir is "push" then Gitteh.GIT_DIR_PUSH else Gitteh.GIT_DIR_FETCH
		nativeRemote.connect dir, wrapCallback cb, (refs) =>
			refNames = Object.keys refs

			# Determine symref for HEAD.
			headOid = refs["HEAD"]
			for ref, oid of refs
				continue if ref is "HEAD"
				if oid is headOid
					headRef = fetchSpec.transformTo ref
					immutable(@, {headRef}).set "headRef", "HEAD"
					break

			immutable(@, {refNames}).set "refNames", "refs"
			connected = true
			cb()
	@fetch = =>
		throw new Error "Remote isn't connected." if not connected
		[progressCb, cb] = args
			progressCb: type: "function"
			cb: type: "function"

		updateTimer = null
		update = =>
			{bytes, total, done} = nativeRemote.stats
			progressCb bytes, total, done
			updateTimer = setTimeout update, 500
		setTimeout update, 500

		nativeRemote.download (err) =>
			clearTimeout updateTimer
			return cb err if err?
			nativeRemote.updateTips wrapCallback cb, =>
				cb()

	return @

wrapCallback = (orig, cb) ->
	return (err) ->
		return orig err if err?
		cb.apply null, Array.prototype.slice.call arguments, 1

Gitteh.Index = Index = (nativeIndex) ->

Gitteh.Repository = Repository = (nativeRepo) ->
	if nativeRepo not instanceof NativeRepository
		throw new Error "Don't construct me, see gitteh.(open|init)Repository"

	immutable(@, nativeRepo)
		.set("bare")

	return @

Gitteh.Refspec = Refspec = (src, dst) ->
	_priv = createPrivate @

	_priv.srcRoot = if src? and src[-1..] is "*" then src[0...-1] else src
	_priv.dstRoot = if dst? and dst[-1..] is "*" then dst[0...-1] else dst

	immutable(@, {src, dst})
		.set("src")
		.set("dst")
	return @
Refspec.prototype.matchesSrc = (ref) ->
	_priv = getPriv @
	return false if ref.length <= _priv.srcRoot.length
	return ref.indexOf(_priv.srcRoot) is 0
Refspec.prototype.matchesDst = (ref) ->
	_priv = getPriv @
	return false if ref.length <= _priv.dstRoot.length
	return ref.indexOf(_priv.dstRoot) is 0
Refspec.prototype.transformTo = (ref) ->
	throw new Error "Ref doesn't match src." if not @matchesSrc ref
	return "#{@dst[0...-2]}#{ref[(@src.length-2)..]}"
Refspec.prototype.transformFrom = (ref) ->
	throw new Error "Ref doesn't match dst." if not @matchesDst ref
	return "#{@src[0...-2]}#{ref[(@dst.length-2)..]}"

Gitteh.Commit = Commit = (@repository, obj) ->
	obj.author = new Signature obj.author
