// insert a new node, such as start or target, to the abstract graph and
		// returns the id of the newly created node in the abstract graph
		// x and y are the positions where I want to put the node
		private int InsertStal(HierarchicalMap map, int nodeId, Position pos, int start)
		{
			// If the node already existed (for instance, it was the an entrance point already
			// existing in the graph, we need to keep track of the previous status in order
			// to be able to restore it once we delete this STAL
			if (map.AbsNodeIds[nodeId] != Constants.NO_NODE)
			{
				m_stalLevel[start] = map.AbstractGraph.GetNodeInfo(map.AbsNodeIds[nodeId]).Level;
				m_stalEdges[start] = map.GetNodeEdges(nodeId);
				m_stalUsed[start] = true;
				return map.AbsNodeIds[nodeId];
			}

			m_stalUsed[start] = false;

			var cluster = map.FindClusterForPosition(pos);

			// create global entrance
			var absNodeId = map.NrNodes;
			var localEntranceIdx = cluster.AddEntrance(absNodeId, new Position(pos.X - cluster.Origin.X, pos.Y - cluster.Origin.Y));
			cluster.UpdatePaths(localEntranceIdx);

			map.AbsNodeIds[nodeId] = absNodeId;

			var info = new AbsTilingNodeInfo(
				absNodeId,
				1,
				cluster.Id,
				pos,
				nodeId,
				localEntranceIdx);

			map.AbstractGraph.AddNode(absNodeId, info);

			// add new edges to the abstract graph
			for (var k = 0; k < cluster.GetNrEntrances() - 1; k++)
			{
				if (cluster.AreConnected(localEntranceIdx, k))
				{
					map.AddEdge(
						cluster.GetGlobalAbsNodeId(k),
						cluster.GetGlobalAbsNodeId(localEntranceIdx),
						cluster.GetDistance(localEntranceIdx, k));
					map.AddEdge(
						cluster.GetGlobalAbsNodeId(localEntranceIdx),
						cluster.GetGlobalAbsNodeId(k),
						cluster.GetDistance(k, localEntranceIdx));
				}
			}

			return absNodeId;
		}
        /// <summary>
        /// Create the asbtract nodes of this graph (composed by the centers of
        /// the entrances between clusters)
        /// </summary>
        private Dictionary<int, AbsTilingNodeInfo> GenerateAbstractNodes(List<Entrance> entrances, List<Cluster> clusters)
        {
            var abstractNodeId = 0;
            var absNodes = new Dictionary<int, AbsTilingNodeInfo>();
            foreach (var entrance in entrances)
            {
                var cluster1 = clusters[entrance.Cluster1Id];
                var cluster2 = clusters[entrance.Cluster2Id];

                // Determine the level of this entrance. It is given
                // by its orientation and its coordinates
                int level;
                switch (entrance.Orientation)
                {
                    case Orientation.HORIZONTAL:
                        level = DetermineLevel(entrance.Coord1.Y);
                        break;
                    case Orientation.VERTICAL:
                        level = DetermineLevel(entrance.Coord1.X);
                        break;
                    default:
                        level = -1;
                        break;
                }

                // use absNodes as a local var to check quickly if a node with the same centerId
                // has been created before
                AbsTilingNodeInfo absNode;
                if (!absNodes.TryGetValue(entrance.Coord1Id, out absNode))
                {
                    var localEntranceIdx = cluster1.AddEntrance(
                        abstractNodeId, 
                        new Position(entrance.Coord1.X - cluster1.Origin.X, entrance.Coord1.Y - cluster1.Origin.Y));
                    
                    var node = new AbsTilingNodeInfo(
                        abstractNodeId, 
                        level,
                        entrance.Cluster1Id,
                        new Position(entrance.Coord1.X, entrance.Coord1.Y),
                        entrance.Coord1Id,
                        localEntranceIdx);
                    absNodes[entrance.Coord1Id] = node;

                    abstractNodeId++;
                }
                else
                {
                    if (level > absNode.Level)
                        absNode.Level = level;
                }

                if (!absNodes.TryGetValue(entrance.Coord2Id, out absNode))
                {
                    var localEntranceIdx = cluster2.AddEntrance(
                        abstractNodeId,
                        new Position(entrance.Coord2.X - cluster2.Origin.X, entrance.Coord2.Y - cluster2.Origin.Y));

                    var node = new AbsTilingNodeInfo(
                        abstractNodeId, 
                        level,	
                        entrance.Cluster2Id,
                        new Position(entrance.Coord2.X, entrance.Coord2.Y),
                        entrance.Coord2Id,
                        localEntranceIdx);
                    absNodes[entrance.Coord2Id] = node;

                    abstractNodeId++;
                }
                else
                {
                    if (level > absNode.Level)
                        absNode.Level = level;
                }
            }

            return absNodes;
        }