def add_node(X):
	# Getting the neighbors
	A = helper.getClosestNode(nodes, X)
	
	if(A and A.nodeKey == X.nodeKey):
		print "node already present-- " + str(X)
		return -1

	
	# Nothing to be done if it's the first node
	if(A == None):
		nodes.append(X)
		return

	routePath = route(A, X)	
	X.routePath = routePath

	Z = routePath[-1]
	
	nodes.append(X)
	
	updateRoutingTable(A, X, routePath)
	updateNeighborSet(A, X)
	updateLeafSet(Z, X)
	
	# Sending state to other nodes
	updateOthers(X)
def nodeDeleted(X):
	X.isNodeActive = False
	for node in nodes:
		# Repair leaf set
		if X in node.upLeafSet:
			node.upLeafSet.remove(X)
			temp = getMaxLeaf(node)
			
			if temp:
				t_leafSet = temp.downLeafSet + temp.upLeafSet
				for leaf in t_leafSet:
					if isEligibleUpLeaf(leaf, node) and leaf not in node.upLeafSet and isNodeAlive(leaf):
						node.upLeafSet.append(leaf)
						break

		elif X in node.downLeafSet:
			node.downLeafSet.remove(X)
			temp = getMinLeaf(node)
			
			if temp:
				t_leafSet = temp.downLeafSet + temp.upLeafSet
				for leaf in t_leafSet:
					if isEligibleDownLeaf(leaf, node) and leaf not in node.downLeafSet and isNodeAlive(leaf):
						node.downLeafSet.append(leaf)
						break
				
		# Repair neighborhood set
		if X in node.neighborhoodSet:
			node.neighborhoodSet.remove(X)
			t_neighborOfNeighborList = []
			# getting all the neighbor of neighbors
			for neighbor in node.neighborhoodSet:
				if(isNodeAlive(neighbor)):
					t_neighborOfNeighborList += neighbor.neighborhoodSet
			
			t_neighborOfNeighborList = list(set(t_neighborOfNeighborList))
			while t_neighborOfNeighborList:
				closestNeighborOfNeighbor = getClosestNode(t_neighborOfNeighborList, node)
				
				if(closestNeighborOfNeighbor.nodeKey == node.nodeKey):
					t_neighborOfNeighborList.remove(closestNeighborOfNeighbor)
					continue
				
				node.neighborhoodSet.append(closestNeighborOfNeighbor)
				break
		
		# Repair routing table
		for routeTableRow in node.routingTable:
			try:
				if X in routeTableRow:
					row = node.routingTable.index(routeTableRow)
					col = routeTableRow.index(X)
					repairRouteTableEntry(node, row, col)
					break
			except ValueError:
				continue
def noisyDelete(X):
	X.isNodeActive = False
	affectedCount = 0
	
	for node in nodes:
		
		if not(isNodeAlive(node)):  # no need to repair the dead nodes
			continue
		
		affectedFlag = False
		
		# Repair leaf set
		if X in node.upLeafSet:
			affectedFlag = True
			node.upLeafSet.remove(X)
			temp = getMaxLeaf(node)
			
			if temp:
				t_leafSet = temp.downLeafSet + temp.upLeafSet
				for leaf in t_leafSet:
					if isEligibleUpLeaf(leaf, node) and leaf not in node.upLeafSet and isNodeAlive(leaf):
						node.upLeafSet.append(leaf)
						break

		elif X in node.downLeafSet:
			affectedFlag = True
			node.downLeafSet.remove(X)
			temp = getMinLeaf(node)
			
			if temp:
				t_leafSet = temp.downLeafSet + temp.upLeafSet
				for leaf in t_leafSet:
					if isEligibleDownLeaf(leaf, node) and leaf not in node.downLeafSet and isNodeAlive(leaf):
						node.downLeafSet.append(leaf)
						break
				
		# Repair neighborhood set
		if X in node.neighborhoodSet:
			affectedFlag = True
			node.neighborhoodSet.remove(X)
			t_neighborOfNeighborList = []
			# getting all the neighbor of neighbors
			for neighbor in node.neighborhoodSet:
				if(isNodeAlive(neighbor)):
					for neighborOfneighbor in neighbor.neighborhoodSet:
						if(isNodeAlive(neighborOfneighbor)):
							t_neighborOfNeighborList.append(neighborOfneighbor)
			
			t_neighborOfNeighborList = list(set(t_neighborOfNeighborList))
			while t_neighborOfNeighborList:
				closestNeighborOfNeighbor = getClosestNode(t_neighborOfNeighborList, node)
				
				try:
					if(closestNeighborOfNeighbor.nodeKey == node.nodeKey):
						t_neighborOfNeighborList.remove(closestNeighborOfNeighbor)
						continue
				
					node.neighborhoodSet.append(closestNeighborOfNeighbor)
					break
				except AttributeError:
					print ("Error")
		
		# Repair routing table
		for routeTableRow in node.routingTable:
			try:
				if X in routeTableRow:
					affectedFlag = True
					row = node.routingTable.index(routeTableRow)
					col = routeTableRow.index(X)
					repairRouteTableEntry(node, row, col)
					break
			except ValueError:
				continue
		
		if affectedFlag:
			affectedCount += 1
		
	return affectedCount