protected void MissionControlText(ContractType contractType)
        {
            string text = "<b><color=#DB8310>Briefing:</color></b>\n\n";

            // Special case for one-off contracts
            string description = contractType.genericDescription;
            if (contractType.maxCompletions == 1)
            {
                foreach (ConfiguredContract c in ConfiguredContract.CompletedContracts)
                {
                    if (c.contractType != null && c.contractType.name == contractType.name)
                    {
                        description = c.Description;
                        break;
                    }
                }
            }
            text += "<color=#CCCCCC>" + description + "</color>\n\n";

            text += "<b><color=#DB8310>Pre-Requisites:</color></b>\n\n";

            // Do text for funds
            if (contractType.advanceFunds < 0)
            {
                CurrencyModifierQuery q = new CurrencyModifierQuery(TransactionReasons.ContractAdvance, -contractType.advanceFunds, 0.0f, 0.0f);
                GameEvents.Modifiers.OnCurrencyModifierQuery.Fire(q);
                float fundsRequired = contractType.advanceFunds + q.GetEffectDelta(Currency.Funds);

                text += RequirementLine("Must have {0} funds for advance", Funding.CanAfford(fundsRequired));
            }

            // Do text for max completions
            if (contractType.maxCompletions != 0)
            {
                int completionCount = contractType.ActualCompletions();
                bool met = completionCount < contractType.maxCompletions;
                if (contractType.maxCompletions == 1)
                {
                    text += RequirementLine("Must not have been completed before", met);
                }
                else
                {
                    text += RequirementLine("May only be completed " + contractType.maxCompletions + " times", met,
                        "has been completed " + completionCount + " times");
                }
            }

            // Do check for group maxSimultaneous
            for (ContractGroup currentGroup = contractType.group; currentGroup != null; currentGroup = currentGroup.parent)
            {
                if (currentGroup.maxSimultaneous != 0)
                {
                    int count = currentGroup.CurrentContracts();
                    text += RequirementLine(string.Format("May only have {0} offered/active {1} contracts at a time",
                        currentGroup.maxSimultaneous, currentGroup.displayName, count), count < currentGroup.maxSimultaneous);
                }
            }

            // Do check of required values
            List<string> titles = new List<string>();
            Dictionary<string, bool> titlesMet = new Dictionary<string, bool>();
            foreach (KeyValuePair<string, ContractType.DataValueInfo> pair in contractType.dataValues)
            {
                string name = pair.Key;
                if (pair.Value.required && !contractType.dataNode.IsDeterministic(name) && !pair.Value.hidden && !pair.Value.IsIgnoredType())
                {
                    bool met = true;
                    try
                    {
                        contractType.CheckRequiredValue(name);
                    }
                    catch
                    {
                        met = false;
                    }

                    string title = string.IsNullOrEmpty(pair.Value.title) ? "Key " + name + " must have a value" : pair.Value.title;
                    if (titlesMet.ContainsKey(title))
                    {
                        titlesMet[title] &= met;
                    }
                    else
                    {
                        titlesMet[title] = met;
                        titles.Add(title);
                    }
                }
            }

            // Do the actual add
            foreach (string title in titles)
            {
                text += RequirementLine(title, titlesMet[title]);
            }

            // Force check requirements for this contract
            CheckRequirements(contractType.Requirements);

            // Do a Research Bodies check, if applicable
            if (Util.Version.VerifyResearchBodiesVersion() && contractType.targetBody != null)
            {
                text += ResearchBodyText(contractType);
            }

            text += ContractRequirementText(contractType.Requirements);

            MissionControl.Instance.contractText.text = text;
        }