public MissionQueueSimple(MissionImpl mission)
        {
            Dictionary<int, MissionNode> IDs = new Dictionary<int, MissionNode>();
            foreach (MissionNode node in mission.MissionNodes)
            {
                if (!IDs.ContainsKey(node.ID))
                {
                    IDs.Add(node.ID, node);

                    m_terminalsRemaining++;
                    m_inEdgeCounts.Add(node, 0);
                    m_outEdges.Add(node, new List<MissionNode>());
                }
            }

            foreach (MissionNode node in IDs.Values)
            {
                foreach (MissionConnection connection in node.Connections)
                {
                    if (connection.SourceID == node.ID ||
                        connection.DestID == node.ID)
                    {
                        MissionNode src = IDs[connection.SourceID];
                        MissionNode dest = IDs[connection.DestID];
                        m_inEdgeCounts[dest]++;
                        m_outEdges[src].Add(dest);

                        if (connection.Edge == MissionEdge.Linear)
                        {
                            dest.Expander.AddLinearRequirement(src.ID.ToString());
                        }
                    }
                    else
                    {
                        throw new Exception("Unknown error in MissionQueueSimple...");
                    }
                }
            }

            foreach (MissionNode node in IDs.Values)
            {
                if (m_inEdgeCounts[node] == 0)
                {
                    m_readyTerminals.Add(node.Expander, node);
                }
            }
        }
        private void ExecuteRule(MissionImpl mission, String rule)
        {
            GraphGrammarRule grammarRule = Rules[rule];
            MissionNode nodeToReplace = null;

            if (mission.MissionNodes.Count == 0)
            {
                MissionNode tempNode = new MissionNode(rule);
                mission.MissionNodes.Add(tempNode);
            }

            foreach (MissionNode node in mission.MissionNodes)
            {
                if (node.Name.Equals(rule))
                {
                    Console.WriteLine("Found Node to Replace: " + node.Name);
                    nodeToReplace = node;
                    break;
                }
            }

            List<MissionNode> missionNodes = new List<MissionNode>();
            for (int i = 0; i < grammarRule.Expansions.Count; i++)
            {
                GraphGrammarRule.Expansion expansion = grammarRule.Expansions[i];
                if (expansion.Probability > RandomManager.get().NextDouble() || i == grammarRule.Expansions.Count - 1)
                {
                    // Use this expansion

                    foreach (String param in expansion.Params)
                    {
                        ParamContainer pc = new ParamContainer(param);
                        nodeToReplace.ParamContainers.Add(pc);
                        mission.ParamContainers.Add(pc);
                    }

                    foreach (KeyValuePair<String, String> mapping in expansion.ResultMappings)
                    {
                        MissionNode node = new MissionNode(mapping.Value, nodeToReplace.ParamContainers);
                        node.expansionID = mapping.Key;

                        Console.WriteLine("Node to add in: " + node.Name);

                        if (!Terminals.ContainsKey(node.Name))
                        {
                            AvailableRules.Add(node.Name);
                            Console.WriteLine("Adding to Available: " + node.Name);
                        }
                        else
                        {
                            node.Expander = Terminals[node.Name].Create(node.ID.ToString());
                        }

                        missionNodes.Add(node);
                    }

                    foreach (KeyValuePair<KeyValuePair<String, String>, MissionEdge> edge in expansion.ResultEdges)
                    {
                        String from = edge.Key.Key;
                        String to = edge.Key.Value;

                        MissionNode fromNode = null;
                        MissionNode toNode = null;

                        foreach (MissionNode node in missionNodes)
                        {
                            if (node.expansionID.Equals(from))
                            {
                                fromNode = node;
                            }
                            if (node.expansionID.Equals(to))
                            {
                                toNode = node;
                            }
                        }
                        MissionConnection tempConnection =
                            new MissionConnection(fromNode.ID, toNode.ID, edge.Value);

                        fromNode.Connections.Add(tempConnection);
                        toNode.Connections.Add(tempConnection);
                    }

                    MissionNode inNode = null;
                    MissionNode outNode = null;

                    foreach (MissionNode node in missionNodes)
                    {
                        if (node.expansionID.Equals(expansion.InNode))
                        {
                            inNode = node;
                        }
                        if (node.expansionID.Equals(expansion.OutNode))
                        {
                            outNode = node;
                        }
                    }

                    foreach (MissionNode node in mission.MissionNodes)
                    {
                        foreach (MissionConnection conn in node.Connections)
                        {
                            if (conn.DestID == nodeToReplace.ID)
                            {
                                conn.DestID = inNode.ID;
                                inNode.Connections.Add(conn);
                            }
                            if (conn.SourceID == nodeToReplace.ID)
                            {
                                conn.SourceID = outNode.ID;
                                outNode.Connections.Add(conn);
                            }
                        }
                    }

                    foreach (MissionConnection conn in nodeToReplace.Connections)
                    {
                        if (conn.DestID == nodeToReplace.ID)
                        {
                            conn.DestID = inNode.ID;
                            inNode.Connections.Add(conn);
                        }
                        if (conn.SourceID == nodeToReplace.ID)
                        {
                            conn.SourceID = outNode.ID;
                            outNode.Connections.Add(conn);
                        }
                    }
                    foreach (MissionNode node in missionNodes)
                    {
                        mission.MissionNodes.Add(node);
                    }
                    mission.MissionNodes.Remove(nodeToReplace);
                    nodeToReplace.freeID();
                    return;
                }
            }
        }
        public IMission WalkGrammar(MetroidAIGameLibrary.player.PlayerModel playerModel)
        {
            /* TODO:
             *  Add Weights to possible paths to take into account the player model
             *  This means I'll have to sort the list of available rules to be best first
             *  Implement a vaild walk of the grammar (basically, everything)
             */
            // start with an empty mission graph, then build it up
            MissionImpl mission = new MissionImpl();

            while (AvailableRules.Count > 0)
            {
                Console.WriteLine("Expanding: " + AvailableRules[0]);
                ExecuteRule(mission, AvailableRules[0]);
                AvailableRules.RemoveAt(0);
            }
            Console.WriteLine("Printing Nodes:");
            foreach (MissionNode node in mission.MissionNodes)
            {
                node.printNode();
            }
            Console.WriteLine("Done Printing Nodes");

            mission.PostProcess();

            return mission;
        }