protected override void OnUpdate()
        {
            base.OnUpdate();
            if (ParameterCount == 0)
            {
                return;
            }
            if (state != ParameterState.Incomplete)
            {
                return;
            }

            if (!KerbalismContractsMain.KerbalismInitialized)
            {
                return;
            }

            if (lastUpdate == 0)
            {
                lastUpdate = Planetarium.GetUniversalTime();
                return;
            }

            bool childParameterChanged = false;

            if (subRequirementParameters.Count == 0)
            {
                childParameterChanged = true;
                CreateSubParameters();
            }

            var lastUpdateAge = Planetarium.GetUniversalTime() - lastUpdate;

            if (lastUpdateAge < 1.0)
            {
                return;
            }
            lastUpdate = Planetarium.GetUniversalTime();

            vessels.Clear();
            context = CreateContext(lastUpdateAge);

            foreach (var sp in subRequirementParameters)
            {
                sp.ResetContext(context);
            }

            foreach (Vessel vessel in FlightGlobals.Vessels)
            {
                if (!Utils.IsVessel(vessel))
                {
                    continue;
                }

                if (!CouldBeCandidate(vessel))
                {
                    continue;
                }

                if (arguments.requireElectricity && !API.IsPowered(vessel))
                {
                    if (!hideChildren)
                    {
                        childParameterChanged |= UpdateVesselStatus(vessel, Lib.Color("#KerCon_NoEC", Lib.Kolor.Red), false);                         // No EC
                    }
                    continue;
                }

                if (arguments.requireCommunication && !API.VesselConnectionLinked(vessel))
                {
                    if (!hideChildren)
                    {
                        childParameterChanged |= UpdateVesselStatus(vessel, Lib.Color("#KerCon_NoComms", Lib.Kolor.Red), false);                         // No Comms
                    }
                    continue;
                }

                vessels.Add(vessel);
            }

            if (!hideChildren)
            {
                foreach (var vsp in vesselStatusParameters)
                {
                    vsp.obsolete = true;
                }
            }

            List <Vessel> vesselsMeetingCondition = new List <Vessel>();

            int stepCount = context.steps.Count;

            for (int i = 0; i < stepCount; i++)
            {
                var now = context.steps[i];
                context.SetTime(now);

                vesselsMeetingCondition.Clear();
                bool doLabelUpdate = !hideChildren && i + 1 == stepCount;

                foreach (Vessel vessel in vessels)
                {
                    // Note considering early termination for performance gains:
                    // If we already know that we have enough vessels to satisfy
                    // our requirement, and if we don't have to update labels,
                    // then we don't need to test all vessels. However, this
                    // doesn't work when we have complex requirements that need
                    // to consider multiple vessels at once (like body surface
                    // observation percentage). We could change the implementation
                    // to continuously integrate one vessel at a time into the
                    // multi-vessel test and abort as soon as that one is satisfied,
                    // but if that also calculates a number visible to the user
                    // (like percentage of surface observed), that number would
                    // be wrong. So we need to test all vessels, all the time.

                    // if (!doLabelUpdate && vesselsMeetingCondition.Count >= minVessels)
                    //	break;

                    string statusLabel;

                    bool conditionMet = VesselMeetsCondition(vessel, doLabelUpdate, out statusLabel);
                    if (conditionMet)
                    {
                        vesselsMeetingCondition.Add(vessel);
                    }

                    if (doLabelUpdate)
                    {
                        childParameterChanged |= UpdateVesselStatus(vessel, statusLabel, conditionMet);
                    }
                }

                bool allConditionsMet = vesselsMeetingCondition.Count >= arguments.minVessels;
                allConditionsMet &= VesselsMeetCondition(vesselsMeetingCondition);

                if (durationParameter == null)
                {
                    SetState(allConditionsMet ? ParameterState.Complete : ParameterState.Incomplete);
                }
                else
                {
                    durationParameter.Update(allConditionsMet, now);
                    SetState(durationParameter.State);
                }

                if (state == ParameterState.Complete)
                {
                    break;
                }
            }

            childParameterChanged |= RemoveObsoleteVesselStatusParameters();
            if (childParameterChanged)
            {
                ContractConfigurator.ContractConfigurator.OnParameterChange.Fire(this.Root, this);
            }
        }