diff --git a/qchess/qchess.py b/qchess/qchess.py
index db73c943907ee3dcf7887230f77508a6e9b7c61f..51e73042a3584ce30342f015774b9d596987abfc 100755
--- a/qchess/qchess.py
+++ b/qchess/qchess.py
@@ -1,4 +1,95 @@
 #!/usr/bin/python -u
+# +++ piece.py +++ #
+import random
+
+# I know using non-abreviated strings is inefficient, but this is python, who cares?
+# Oh, yeah, this stores the number of pieces of each type in a normal chess game
+piece_types = {"pawn" : 8, "bishop" : 2, "knight" : 2, "rook" : 2, "queen" : 1, "king" : 1, "unknown" : 0}
+
+# Class to represent a quantum chess piece
+class Piece():
+	def __init__(self, colour, x, y, types):
+		self.colour = colour # Colour (string) either "white" or "black"
+		self.x = x # x coordinate (0 - 8), none of this fancy 'a', 'b' shit here
+		self.y = y # y coordinate (0 - 8)
+		self.types = types # List of possible types the piece can be (should just be two)
+		self.current_type = "unknown" # Current type
+		self.choice = -1 # Index of the current type in self.types (-1 = unknown type)
+		self.types_revealed = [True, False] # Whether the types are known (by default the first type is always known at game start)
+		
+
+		# 
+		self.last_state = None
+		self.move_pattern = None
+
+		
+
+	def init_from_copy(self, c):
+		self.colour = c.colour
+		self.x = c.x
+		self.y = c.y
+		self.types = c.types[:]
+		self.current_type = c.current_type
+		self.choice = c.choice
+		self.types_revealed = c.types_revealed[:]
+
+		self.last_state = None
+		self.move_pattern = None
+
+	
+
+	# Make a string for the piece (used for debug)
+	def __str__(self):
+		return str(self.current_type) + " " + str(self.types) + " at " + str(self.x) + ","+str(self.y)  
+
+	# Draw the piece in a pygame surface
+	def draw(self, window, grid_sz = [80,80]):
+
+		# First draw the image corresponding to self.current_type
+		img = images[self.colour][self.current_type]
+		rect = img.get_rect()
+		offset = [-rect.width/2,-3*rect.height/4] 
+		window.blit(img, (self.x * grid_sz[0] + grid_sz[0]/2 + offset[0], self.y * grid_sz[1] + grid_sz[1]/2 + offset[1]))
+		
+		
+		# Draw the two possible types underneath the current_type image
+		for i in range(len(self.types)):
+			if self.types_revealed[i] == True:
+				img = small_images[self.colour][self.types[i]]
+			else:
+				img = small_images[self.colour]["unknown"] # If the type hasn't been revealed, show a placeholder
+
+			
+			rect = img.get_rect()
+			offset = [-rect.width/2,-rect.height/2] 
+			
+			if i == 0:
+				target = (self.x * grid_sz[0] + grid_sz[0]/5 + offset[0], self.y * grid_sz[1] + 3*grid_sz[1]/4 + offset[1])				
+			else:
+				target = (self.x * grid_sz[0] + 4*grid_sz[0]/5 + offset[0], self.y * grid_sz[1] + 3*grid_sz[1]/4 + offset[1])				
+				
+			window.blit(img, target) # Blit shit
+	
+	# Collapses the wave function!		
+	def select(self):
+		if self.current_type == "unknown":
+			self.choice = random.randint(0,1)
+			self.current_type = self.types[self.choice]
+			self.types_revealed[self.choice] = True
+		return self.choice
+
+	# Uncollapses (?) the wave function!
+	def deselect(self):
+		#print "Deselect called"
+		if (self.x + self.y) % 2 != 0:
+			if (self.types[0] != self.types[1]) or (self.types_revealed[0] == False or self.types_revealed[1] == False):
+				self.current_type = "unknown"
+				self.choice = -1
+			else:
+				self.choice = 0 # Both the two types are the same
+
+	# The sad moment when you realise that you do not understand anything about a subject you studied for 4 years...
+# --- piece.py --- #
 # +++ board.py +++ #
 [w,h] = [8,8] # Width and height of board(s)
 
@@ -404,79 +495,256 @@ class Board():
 	def on_board(self, x, y):
 		return (x >= 0 and x < w) and (y >= 0 and y < h)
 # --- board.py --- #
-# +++ game.py +++ #
-
-# A thread that runs the game
-class GameThread(StoppableThread):
-	def __init__(self, board, players):
-		StoppableThread.__init__(self)
-		self.board = board
-		self.players = players
-		self.state = {"turn" : None} # The game state
-		self.error = 0 # Whether the thread exits with an error
-		self.lock = threading.RLock() #lock for access of self.state
-		self.cond = threading.Condition() # conditional for some reason, I forgot
-		self.final_result = ""
+# +++ player.py +++ #
+import subprocess
 
-	# Run the game (run in new thread with start(), run in current thread with run())
-	def run(self):
-		result = ""
-		while not self.stopped():
-			
-			for p in self.players:
-				with self.lock:
-					self.state["turn"] = p # "turn" contains the player who's turn it is
-				#try:
-				if True:
-					[x,y] = p.select() # Player selects a square
-					if self.stopped():
-						break
 
-					result = self.board.select(x, y, colour = p.colour)				
-					for p2 in self.players:
-						p2.update(result) # Inform players of what happened
 
+# A player who can't play
+class Player():
+	def __init__(self, name, colour):
+		self.name = name
+		self.colour = colour
 
+# Player that runs from another process
+class AgentPlayer(Player):
+	def __init__(self, name, colour):
+		Player.__init__(self, name, colour)
+		self.p = subprocess.Popen(name, stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=sys.stderr)
+		try:
+			self.p.stdin.write(colour + "\n")
+		except:
+			raise Exception("UNRESPONSIVE")
 
-					target = self.board.grid[x][y]
-					if isinstance(graphics, GraphicsThread):
-						with graphics.lock:
-							graphics.state["moves"] = self.board.possible_moves(target)
-							graphics.state["select"] = target
+	def select(self):
+		
+		#try:
+		self.p.stdin.write("SELECTION?\n")
+		line = self.p.stdout.readline().strip("\r\n ")
+		#except:
+		#	raise Exception("UNRESPONSIVE")
+		try:
+			result = map(int, line.split(" "))
+		except:
+			raise Exception("GIBBERISH \"" + str(line) + "\"")
+		return result
 
-					time.sleep(turn_delay)
+	def update(self, result):
+		#print "Update " + str(result) + " called for AgentPlayer"
+#		try:
+		self.p.stdin.write(result + "\n")
+#		except:
+#		raise Exception("UNRESPONSIVE")
 
+	def get_move(self):
+		
+		try:
+			self.p.stdin.write("MOVE?\n")
+			line = self.p.stdout.readline().strip("\r\n ")
+		except:
+			raise Exception("UNRESPONSIVE")
+		try:
+			result = map(int, line.split(" "))
+		except:
+			raise Exception("GIBBERISH \"" + str(line) + "\"")
+		return result
 
-					if len(self.board.possible_moves(target)) == 0:
-						#print "Piece cannot move"
-						target.deselect()
-						if isinstance(graphics, GraphicsThread):
-							with graphics.lock:
-								graphics.state["moves"] = None
-								graphics.state["select"] = None
-								graphics.state["dest"] = None
-						continue
+	def quit(self, final_result):
+		try:
+			self.p.stdin.write("QUIT " + final_result + "\n")
+		except:
+			self.p.kill()
 
-					try:
-						[x2,y2] = p.get_move() # Player selects a destination
-					except:
-						self.stop()
+# So you want to be a player here?
+class HumanPlayer(Player):
+	def __init__(self, name, colour):
+		Player.__init__(self, name, colour)
+		
+	# Select your preferred account
+	def select(self):
+		if isinstance(graphics, GraphicsThread):
+			# Basically, we let the graphics thread do some shit and then return that information to the game thread
+			graphics.cond.acquire()
+			# We wait for the graphics thread to select a piece
+			while graphics.stopped() == False and graphics.state["select"] == None:
+				graphics.cond.wait() # The difference between humans and machines is that humans sleep
+			select = graphics.state["select"]
+			
+			
+			graphics.cond.release()
+			if graphics.stopped():
+				return [-1,-1]
+			return [select.x, select.y]
+		else:
+			# Since I don't display the board in this case, I'm not sure why I filled it in...
+			while True:
+				sys.stdout.write("SELECTION?\n")
+				try:
+					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
+				except:
+					sys.stderr.write("ILLEGAL GIBBERISH\n")
+					continue
+	# It's your move captain
+	def get_move(self):
+		if isinstance(graphics, GraphicsThread):
+			graphics.cond.acquire()
+			while graphics.stopped() == False and graphics.state["dest"] == None:
+				graphics.cond.wait()
+			graphics.cond.release()
+			
+			return graphics.state["dest"]
+		else:
 
-					if self.stopped():
-						break
+			while True:
+				sys.stdout.write("MOVE?\n")
+				try:
+					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
+				except:
+					sys.stderr.write("ILLEGAL GIBBERISH\n")
+					continue
 
-					result = self.board.update_move(x, y, x2, y2)
-					for p2 in self.players:
-						p2.update(str(x) + " " + str(y) + " -> " + str(x2) + " " + str(y2)) # Inform players of what happened
+	# Are you sure you want to quit?
+	def quit(self, final_result):
+		sys.stdout.write("QUIT " + final_result + "\n")
 
-					if isinstance(graphics, GraphicsThread):
-						with graphics.lock:
-							graphics.state["moves"] = [[x2,y2]]
+	# Completely useless function
+	def update(self, result):
+		if isinstance(graphics, GraphicsThread):
+			pass
+		else:
+			sys.stdout.write(result + "\n")	
 
-					time.sleep(turn_delay)
 
-					if isinstance(graphics, GraphicsThread):
-						with graphics.lock:
+# Player that makes random moves
+class AgentRandom(Player):
+	def __init__(self, name, colour):
+		Player.__init__(self, name, colour)
+		self.choice = None
+
+		self.board = Board(style = "agent")
+
+	def select(self):
+		while True:
+			self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)]
+			all_moves = []
+			# Check that the piece has some possibility to move
+			tmp = self.choice.current_type
+			if tmp == "unknown": # For unknown pieces, try both types
+				for t in self.choice.types:
+					if t == "unknown":
+						continue
+					self.choice.current_type = t
+					all_moves += self.board.possible_moves(self.choice)
+			else:
+				all_moves = self.board.possible_moves(self.choice)
+			self.choice.current_type = tmp
+			if len(all_moves) > 0:
+				break
+		return [self.choice.x, self.choice.y]
+
+	def get_move(self):
+		moves = self.board.possible_moves(self.choice)
+		move = moves[random.randint(0, len(moves)-1)]
+		return move
+
+	def update(self, result):
+		#sys.stderr.write(sys.argv[0] + " : Update board for AgentRandom\n")
+		self.board.update(result)
+		self.board.verify()
+
+	def quit(self, final_result):
+		pass
+# --- player.py --- #
+# +++ thread_util.py +++ #
+import threading
+
+# A thread that can be stopped!
+# Except it can only be stopped if it checks self.stopped() periodically
+# So it can sort of be stopped
+class StoppableThread(threading.Thread):
+	def __init__(self):
+		threading.Thread.__init__(self)
+		self._stop = threading.Event()
+
+	def stop(self):
+		self._stop.set()
+
+	def stopped(self):
+		return self._stop.isSet()
+# --- thread_util.py --- #
+# +++ game.py +++ #
+
+# A thread that runs the game
+class GameThread(StoppableThread):
+	def __init__(self, board, players):
+		StoppableThread.__init__(self)
+		self.board = board
+		self.players = players
+		self.state = {"turn" : None} # The game state
+		self.error = 0 # Whether the thread exits with an error
+		self.lock = threading.RLock() #lock for access of self.state
+		self.cond = threading.Condition() # conditional for some reason, I forgot
+		self.final_result = ""
+
+	# Run the game (run in new thread with start(), run in current thread with run())
+	def run(self):
+		result = ""
+		while not self.stopped():
+			
+			for p in self.players:
+				with self.lock:
+					self.state["turn"] = p # "turn" contains the player who's turn it is
+				#try:
+				if True:
+					[x,y] = p.select() # Player selects a square
+					if self.stopped():
+						break
+
+					result = self.board.select(x, y, colour = p.colour)				
+					for p2 in self.players:
+						p2.update(result) # Inform players of what happened
+
+
+
+					target = self.board.grid[x][y]
+					if isinstance(graphics, GraphicsThread):
+						with graphics.lock:
+							graphics.state["moves"] = self.board.possible_moves(target)
+							graphics.state["select"] = target
+
+					time.sleep(turn_delay)
+
+
+					if len(self.board.possible_moves(target)) == 0:
+						#print "Piece cannot move"
+						target.deselect()
+						if isinstance(graphics, GraphicsThread):
+							with graphics.lock:
+								graphics.state["moves"] = None
+								graphics.state["select"] = None
+								graphics.state["dest"] = None
+						continue
+
+					try:
+						[x2,y2] = p.get_move() # Player selects a destination
+					except:
+						self.stop()
+
+					if self.stopped():
+						break
+
+					result = self.board.update_move(x, y, x2, y2)
+					for p2 in self.players:
+						p2.update(str(x) + " " + str(y) + " -> " + str(x2) + " " + str(y2)) # Inform players of what happened
+
+					if isinstance(graphics, GraphicsThread):
+						with graphics.lock:
+							graphics.state["moves"] = [[x2,y2]]
+
+					time.sleep(turn_delay)
+
+					if isinstance(graphics, GraphicsThread):
+						with graphics.lock:
 							graphics.state["select"] = None
 							graphics.state["dest"] = None
 							graphics.state["moves"] = None
@@ -874,271 +1142,4 @@ def main(argv):
 if __name__ == "__main__":
 	sys.exit(main(sys.argv))
 # --- main.py --- #
-# +++ piece.py +++ #
-import random
-
-# I know using non-abreviated strings is inefficient, but this is python, who cares?
-# Oh, yeah, this stores the number of pieces of each type in a normal chess game
-piece_types = {"pawn" : 8, "bishop" : 2, "knight" : 2, "rook" : 2, "queen" : 1, "king" : 1, "unknown" : 0}
-
-# Class to represent a quantum chess piece
-class Piece():
-	def __init__(self, colour, x, y, types):
-		self.colour = colour # Colour (string) either "white" or "black"
-		self.x = x # x coordinate (0 - 8), none of this fancy 'a', 'b' shit here
-		self.y = y # y coordinate (0 - 8)
-		self.types = types # List of possible types the piece can be (should just be two)
-		self.current_type = "unknown" # Current type
-		self.choice = -1 # Index of the current type in self.types (-1 = unknown type)
-		self.types_revealed = [True, False] # Whether the types are known (by default the first type is always known at game start)
-		
-
-		# 
-		self.last_state = None
-		self.move_pattern = None
-
-		
-
-	def init_from_copy(self, c):
-		self.colour = c.colour
-		self.x = c.x
-		self.y = c.y
-		self.types = c.types[:]
-		self.current_type = c.current_type
-		self.choice = c.choice
-		self.types_revealed = c.types_revealed[:]
-
-		self.last_state = None
-		self.move_pattern = None
-
-	
-
-	# Make a string for the piece (used for debug)
-	def __str__(self):
-		return str(self.current_type) + " " + str(self.types) + " at " + str(self.x) + ","+str(self.y)  
-
-	# Draw the piece in a pygame surface
-	def draw(self, window, grid_sz = [80,80]):
-
-		# First draw the image corresponding to self.current_type
-		img = images[self.colour][self.current_type]
-		rect = img.get_rect()
-		offset = [-rect.width/2,-3*rect.height/4] 
-		window.blit(img, (self.x * grid_sz[0] + grid_sz[0]/2 + offset[0], self.y * grid_sz[1] + grid_sz[1]/2 + offset[1]))
-		
-		
-		# Draw the two possible types underneath the current_type image
-		for i in range(len(self.types)):
-			if self.types_revealed[i] == True:
-				img = small_images[self.colour][self.types[i]]
-			else:
-				img = small_images[self.colour]["unknown"] # If the type hasn't been revealed, show a placeholder
-
-			
-			rect = img.get_rect()
-			offset = [-rect.width/2,-rect.height/2] 
-			
-			if i == 0:
-				target = (self.x * grid_sz[0] + grid_sz[0]/5 + offset[0], self.y * grid_sz[1] + 3*grid_sz[1]/4 + offset[1])				
-			else:
-				target = (self.x * grid_sz[0] + 4*grid_sz[0]/5 + offset[0], self.y * grid_sz[1] + 3*grid_sz[1]/4 + offset[1])				
-				
-			window.blit(img, target) # Blit shit
-	
-	# Collapses the wave function!		
-	def select(self):
-		if self.current_type == "unknown":
-			self.choice = random.randint(0,1)
-			self.current_type = self.types[self.choice]
-			self.types_revealed[self.choice] = True
-		return self.choice
-
-	# Uncollapses (?) the wave function!
-	def deselect(self):
-		#print "Deselect called"
-		if (self.x + self.y) % 2 != 0:
-			if (self.types[0] != self.types[1]) or (self.types_revealed[0] == False or self.types_revealed[1] == False):
-				self.current_type = "unknown"
-				self.choice = -1
-			else:
-				self.choice = 0 # Both the two types are the same
-
-	# The sad moment when you realise that you do not understand anything about a subject you studied for 4 years...
-# --- piece.py --- #
-# +++ player.py +++ #
-import subprocess
-
-
-
-# A player who can't play
-class Player():
-	def __init__(self, name, colour):
-		self.name = name
-		self.colour = colour
-
-# Player that runs from another process
-class AgentPlayer(Player):
-	def __init__(self, name, colour):
-		Player.__init__(self, name, colour)
-		self.p = subprocess.Popen(name, stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=sys.stderr)
-		try:
-			self.p.stdin.write(colour + "\n")
-		except:
-			raise Exception("UNRESPONSIVE")
-
-	def select(self):
-		
-		#try:
-		self.p.stdin.write("SELECTION?\n")
-		line = self.p.stdout.readline().strip("\r\n ")
-		#except:
-		#	raise Exception("UNRESPONSIVE")
-		try:
-			result = map(int, line.split(" "))
-		except:
-			raise Exception("GIBBERISH \"" + str(line) + "\"")
-		return result
-
-	def update(self, result):
-		#print "Update " + str(result) + " called for AgentPlayer"
-#		try:
-		self.p.stdin.write(result + "\n")
-#		except:
-#		raise Exception("UNRESPONSIVE")
-
-	def get_move(self):
-		
-		try:
-			self.p.stdin.write("MOVE?\n")
-			line = self.p.stdout.readline().strip("\r\n ")
-		except:
-			raise Exception("UNRESPONSIVE")
-		try:
-			result = map(int, line.split(" "))
-		except:
-			raise Exception("GIBBERISH \"" + str(line) + "\"")
-		return result
-
-	def quit(self, final_result):
-		try:
-			self.p.stdin.write("QUIT " + final_result + "\n")
-		except:
-			self.p.kill()
-
-# So you want to be a player here?
-class HumanPlayer(Player):
-	def __init__(self, name, colour):
-		Player.__init__(self, name, colour)
-		
-	# Select your preferred account
-	def select(self):
-		if isinstance(graphics, GraphicsThread):
-			# Basically, we let the graphics thread do some shit and then return that information to the game thread
-			graphics.cond.acquire()
-			# We wait for the graphics thread to select a piece
-			while graphics.stopped() == False and graphics.state["select"] == None:
-				graphics.cond.wait() # The difference between humans and machines is that humans sleep
-			select = graphics.state["select"]
-			
-			
-			graphics.cond.release()
-			if graphics.stopped():
-				return [-1,-1]
-			return [select.x, select.y]
-		else:
-			# Since I don't display the board in this case, I'm not sure why I filled it in...
-			while True:
-				sys.stdout.write("SELECTION?\n")
-				try:
-					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
-				except:
-					sys.stderr.write("ILLEGAL GIBBERISH\n")
-					continue
-	# It's your move captain
-	def get_move(self):
-		if isinstance(graphics, GraphicsThread):
-			graphics.cond.acquire()
-			while graphics.stopped() == False and graphics.state["dest"] == None:
-				graphics.cond.wait()
-			graphics.cond.release()
-			
-			return graphics.state["dest"]
-		else:
-
-			while True:
-				sys.stdout.write("MOVE?\n")
-				try:
-					p = map(int, sys.stdin.readline().strip("\r\n ").split(" "))
-				except:
-					sys.stderr.write("ILLEGAL GIBBERISH\n")
-					continue
-
-	# Are you sure you want to quit?
-	def quit(self, final_result):
-		sys.stdout.write("QUIT " + final_result + "\n")
-
-	# Completely useless function
-	def update(self, result):
-		if isinstance(graphics, GraphicsThread):
-			pass
-		else:
-			sys.stdout.write(result + "\n")	
-
-
-# Player that makes random moves
-class AgentRandom(Player):
-	def __init__(self, name, colour):
-		Player.__init__(self, name, colour)
-		self.choice = None
-
-		self.board = Board(style = "agent")
-
-	def select(self):
-		while True:
-			self.choice = self.board.pieces[self.colour][random.randint(0, len(self.board.pieces[self.colour])-1)]
-			all_moves = []
-			# Check that the piece has some possibility to move
-			tmp = self.choice.current_type
-			if tmp == "unknown": # For unknown pieces, try both types
-				for t in self.choice.types:
-					if t == "unknown":
-						continue
-					self.choice.current_type = t
-					all_moves += self.board.possible_moves(self.choice)
-			else:
-				all_moves = self.board.possible_moves(self.choice)
-			self.choice.current_type = tmp
-			if len(all_moves) > 0:
-				break
-		return [self.choice.x, self.choice.y]
-
-	def get_move(self):
-		moves = self.board.possible_moves(self.choice)
-		move = moves[random.randint(0, len(moves)-1)]
-		return move
-
-	def update(self, result):
-		#sys.stderr.write(sys.argv[0] + " : Update board for AgentRandom\n")
-		self.board.update(result)
-		self.board.verify()
-
-	def quit(self, final_result):
-		pass
-# --- player.py --- #
-# +++ thread_util.py +++ #
-import threading
-
-# A thread that can be stopped!
-# Except it can only be stopped if it checks self.stopped() periodically
-# So it can sort of be stopped
-class StoppableThread(threading.Thread):
-	def __init__(self):
-		threading.Thread.__init__(self)
-		self._stop = threading.Event()
-
-	def stop(self):
-		self._stop.set()
-
-	def stopped(self):
-		return self._stop.isSet()
-# --- thread_util.py --- #
+# EOF - created from update.sh on Wed Jan 23 22:01:52 WST 2013
diff --git a/qchess/update.sh b/qchess/update.sh
index 0edb377391c5d9c6c8e1fcb89475b30574f6a34c..a60ca80466f8c15a901d2dc1656e56e2836af268 100755
--- a/qchess/update.sh
+++ b/qchess/update.sh
@@ -2,6 +2,8 @@
 
 # I still can't believe I am doing this
 
+# (This can't be done with gnu make, because of circular dependency issues)
+
 target=qchess.py
 components="piece.py board.py player.py thread_util.py game.py graphics.py main.py"
 # The below seems nicer, but doesn't work because things need to be imported in the right order :(
@@ -13,22 +15,52 @@ footer="# EOF - created from update.sh on $(date)"
 
 
 # If the target was modified more recently than any of the components, update the component file
-target_mod=$(stat -c %Y $target)
+target_mod=$(stat -c %Y $target 2>/dev/null)
+
+if [ $? -ne 0 ]; then
+	merge_required=true
+else
+	merge_required=false
 
-merge_required=false
+	for f in $components; do
+		
+		component_mod=$(stat -c %Y $f 2>/dev/null)
+		if [ $? -ne 0 ]; then
+			update_required=true
+		elif [ $component_mod -lt $target_mod ]; then
+			update_required=true
+		else
+			update_required=false
+		fi
 
-for f in $components; do
-	if [ $(stat -c %Y $f) -lt $target_mod ]; then
-		nawk "/+++ $f +++/, /--- $f ---/" $target | grep -v "+++ $f +++" | grep -v "\--- $f ---" > $f
-	else
-		merge_required=true
-done
+		if $update_required; then
+			echo "$0 - update $f from $target"
+			sanity=$(egrep "(+++ $f +++)|(--- $f ---)" $target | wc -l)
+			if [ $sanity -ne 2 ]; then
+				$(echo "$0 - $target does not have markers for $f in it!") 1>&2
+				exit 1
+			fi
+			cp $f $f~
+			new_contents=$(nawk "/+++ $f +++/, /--- $f ---/" $target | grep -v "+++ $f +++" | grep -v "\--- $f ---")
+			
+			echo "$new_contents" > $f
+		else
+			echo "$0 - $f is newer than $target"
+			merge_required=true
+		fi
+	done
+fi
 
+# If any components were modified more recently than the target, merge the components into the target
 if $merge_required; then
 	echo $header > $target
 	for f in $components; do
-		cat $components >> $target
+		echo "$0 - merge $f into $target"
+		echo "# +++ $f +++ #" >> $target
+		cat $f >> $target
+		echo "# --- $f --- #" >> $target
 	done
 
-	echo $footer > $target
+	echo $footer >> $target
+	chmod u+x $target
 fi