/// <summary>
        /// Copies crew assignments from the dialog to the ship construct.
        /// </summary>
        private void CopyCrew()
        {
            VesselCrewManifest dialogVessel = CurrentDialogContents;

            if (dialogVessel == null)
            {
                Logging.Error("No dialog manifest, can't copy");
                return;
            }
            VesselCrewManifest      currentVessel = ShipConstruction.ShipManifest;
            List <PartCrewManifest> dialogParts   = dialogVessel.GetCrewableParts();
            List <PartCrewManifest> currentParts  = currentVessel.GetCrewableParts();

            if (dialogParts.Count != currentParts.Count)
            {
                Logging.Error("Crew dialog has " + dialogParts.Count
                              + " crewable parts, but vessel has only " + currentParts.Count + ". Can't copy.");
                return;
            }
            for (int partIndex = 0; partIndex < dialogParts.Count; ++partIndex)
            {
                PartCrewManifest  dialogPart  = dialogParts[partIndex];
                PartCrewManifest  currentPart = currentParts[partIndex];
                ProtoCrewMember[] dialogCrew  = dialogPart.GetPartCrew();
                ProtoCrewMember[] currentCrew = currentPart.GetPartCrew();
                if ((dialogPart.PartID != currentPart.PartID) || (dialogCrew.Length != currentCrew.Length))
                {
                    Logging.Error("Mismatched manifests at index " + partIndex + ", can't copy.");
                    return;
                }
                for (int slotIndex = 0; slotIndex < dialogCrew.Length; ++slotIndex)
                {
                    ProtoCrewMember dialogMember  = dialogCrew[slotIndex];
                    ProtoCrewMember currentMember = currentCrew[slotIndex];
                    if (!AreSame(dialogMember, currentMember))
                    {
                        Logging.Log("Crew change in " + currentPart.PartInfo.title + " slot " + slotIndex + ": "
                                    + DescribeCrew(currentMember) + " -> " + DescribeCrew(dialogMember));
                        currentPart.RemoveCrewFromSeat(slotIndex);
                        if (dialogMember != null)
                        {
                            if (currentVessel.Contains(dialogMember))
                            {
                                PartCrewManifest previousPart = currentVessel.GetPartForCrew(dialogMember);
                                previousPart.RemoveCrewFromSeat(previousPart.GetCrewSeat(dialogMember));
                            }
                            currentPart.AddCrewToSeat(dialogMember, slotIndex);
                        }
                    } // if there's an assignment difference
                }     // for each slot in the part
            }         // for each crewable part in the vessel
        }
        /// <summary>
        /// Copies crew assignments from the dialog to the ship construct.
        /// </summary>
        private void CopyCrew()
        {
            VesselCrewManifest dialogVessel = CurrentDialogContents;

            if (dialogVessel == null)
            {
                return;
            }
            VesselCrewManifest      currentVessel = ShipConstruction.ShipManifest;
            List <PartCrewManifest> dialogParts   = dialogVessel.GetCrewableParts();
            List <PartCrewManifest> currentParts  = currentVessel.GetCrewableParts();

            if (dialogParts.Count != currentParts.Count)
            {
                return;
            }
            for (int partIndex = 0; partIndex < dialogParts.Count; ++partIndex)
            {
                PartCrewManifest  dialogPart  = dialogParts[partIndex];
                PartCrewManifest  currentPart = currentParts[partIndex];
                ProtoCrewMember[] dialogCrew  = dialogPart.GetPartCrew();
                ProtoCrewMember[] currentCrew = currentPart.GetPartCrew();
                if ((dialogPart.PartID != currentPart.PartID) || (dialogCrew.Length != currentCrew.Length))
                {
                    return;
                }
                for (int slotIndex = 0; slotIndex < dialogCrew.Length; ++slotIndex)
                {
                    ProtoCrewMember dialogMember  = dialogCrew[slotIndex];
                    ProtoCrewMember currentMember = currentCrew[slotIndex];
                    if (!AreSame(dialogMember, currentMember))
                    {
                        currentPart.RemoveCrewFromSeat(slotIndex);
                        if (dialogMember != null)
                        {
                            if (currentVessel.Contains(dialogMember))
                            {
                                PartCrewManifest previousPart = currentVessel.GetPartForCrew(dialogMember);
                                previousPart.RemoveCrewFromSeat(previousPart.GetCrewSeat(dialogMember));
                            }
                            currentPart.AddCrewToSeat(dialogMember, slotIndex);
                        }
                    } // if there's an assignment difference
                }     // for each slot in the part
            }         // for each crewable part in the vessel
        }
        public static IEnumerable <ProtoCrewMember> AddCrewToOpenSeats(this PartCrewManifest crewManifest, IEnumerable <ProtoCrewMember> crewMembers)
        {
            // crewManifest.GetPartCrew() is a statically-sized array with null elements
            IEnumerable <int> openSeatIndexes = crewManifest.GetPartCrew().Select((x, index) => new { x, index }).Where(x => x.x == null).Select(x => x.index);

            // Need to know the number of excluded elements
            int openSeatIndexesCount = openSeatIndexes.ToArray().Length;

            // Get the members we are going to assign
            IEnumerator <ProtoCrewMember> crewEnumerator = crewMembers.Take(openSeatIndexesCount).GetEnumerator();

#if DEBUG
            Logging.Debug("indexLength:" + openSeatIndexes.ToArray().Length);
            foreach (int i in openSeatIndexes)
            {
                Logging.Debug("indexes:" + i);
            }

            foreach (ProtoCrewMember crew in crewMembers.Take(openSeatIndexesCount))
            {
                Logging.Debug("crew:" + crew.name);
            }
#endif

            foreach (int index in openSeatIndexes)
            {
                if (crewEnumerator.MoveNext())
                {
                    crewManifest.AddCrewToSeat(crewEnumerator.Current, index);
                }
                else
                {
                    return(crewMembers.Skip(openSeatIndexesCount));;
                }
            }

            // return the remainders
            return(crewMembers.Skip(openSeatIndexesCount));;
        }