/// <summary>
        /// Adds a new operating system.
        /// </summary>
        /// <param name="operatingSystem">The new operating system.</param>
        public void Add(OperatingSystemDescription operatingSystem)
        {
            VerifySchemaVersion();

            var result = StoredOperatingSystemDescriptions.Add(operatingSystem);
            Patch(result);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="OperatingSystemModel"/> class.
        /// </summary>
        /// <param name="model">The object that handles the data storage.</param>
        /// <exception cref="ArgumentNullException">
        ///     Thrown if <paramref name="model"/> is <see langword="null" />.
        /// </exception>
        public OperatingSystemModel(OperatingSystemDescription model)
        {
            {
                Lokad.Enforce.Argument(() => model);
            }

            m_Model = model;
        }
        private OperatingSystemDescription Patch(OperatingSystemDescription description)
        {
            var result = StoredOperatingSystemDescriptions.Find(description.Id) ?? StoredOperatingSystemDescriptions.Add(description);
            if (!result.IsPatched && !result.IsPatching)
            {
                result.IsPatching = true;
                try
                {
                    var selectedMachines = GetMachinesByOperatingSystemId(result.Id)
                        .Select(Machine)
                        .ToList();
                    result.Machines = selectedMachines;

                    var selectedEnvironments = GetTestEnvironmentByOperatingSystemId(result.Id)
                        .Select(id => TestEnvironment(id.Value))
                        .ToList();
                    result.TestEnvironments = selectedEnvironments;

                    result.IsPatched = true;
                }
                finally
                {
                    result.IsPatching = false;
                }
            }

            return description;
        }
        private OperatingSystemDescription GetStoredOperatingSystemFromData(OperatingSystemDescription operatingSystem)
        {
            var storedOs = GetOperatingSystemsByName(
                operatingSystem.Name,
                operatingSystem.ServicePack,
                operatingSystem.ArchitecturePointerSize,
                operatingSystem.Culture)
                .FirstOrDefault();
            if (storedOs == null)
            {
                throw new UnknownOperatingSystemException();
            }

            return Patch(storedOs);
        }
 private static void CopyPropertyValues(OperatingSystemDescription stored, OperatingSystemDescription operatingSystem)
 {
     stored.Name = operatingSystem.Name;
     stored.ServicePack = operatingSystem.ServicePack;
     stored.PointerSize = operatingSystem.PointerSize;
     stored.CultureInfo = operatingSystem.CultureInfo;
 }
        /// <summary>
        /// Updates the operating system with the data from the given object.
        /// </summary>
        /// <param name="operatingSystem">The operating system.</param>
        public void Update(OperatingSystemDescription operatingSystem)
        {
            VerifySchemaVersion();

            var storedOperatingSystem = OperatingSystem(operatingSystem.Id);
            if (storedOperatingSystem != null)
            {
                if (!ReferenceEquals(storedOperatingSystem, operatingSystem))
                {
                    CopyPropertyValues(storedOperatingSystem, operatingSystem);
                }

                var entry = Entry(storedOperatingSystem);
                entry.State = EntityState.Modified;
            }
        }
        /// <summary>
        /// Returns a collection containing all the inactive machines that have the specified operating system
        /// and the specified set of applications.
        /// </summary>
        /// <param name="operatingSystem">The required operation system.</param>
        /// <param name="applications">The collection of required applications.</param>
        /// <returns>A collection containing all inactive machines with the specified operating system and the specified applications.</returns>
        public IEnumerable<MachineDescription> InactiveMachinesWith(
            OperatingSystemDescription operatingSystem,
            IEnumerable<ApplicationDescription> applications)
        {
            VerifySchemaVersion();

            // Make sure we have a complete OperatingSystemDescription object, including IDs
            var storedOs = GetStoredOperatingSystemFromData(operatingSystem);

            // Make sure we have complete ApplicationDescription objects, including IDs
            var storedApplications = new List<ApplicationDescription>();
            foreach (var app in applications)
            {
                var storedApp = GetStoredApplicationFromData(app);
                storedApplications.Add(storedApp);
            }

            var selectedMachines = GetMachinesByOperatingSystemId(storedOs.Id).ToList();
            foreach (var app in storedApplications)
            {
                var machinesWithApp = GetMachinesByApplicationId(app.Id).ToList();
                selectedMachines = selectedMachines.Intersect(machinesWithApp).ToList();
                if (!selectedMachines.Any())
                {
                    throw new FailedToLocateEnvironmentException();
                }
            }

            return selectedMachines
                .Select(Machine)
                .Where(m => m.IsAvailableForTesting && !m.IsActive)
                .ToList();
        }