public void TestOpenCloseControlled()
        {
            const string strProviderName           = "Sample Source Control Provider:{B0BAC05D-2000-41D1-A6C3-704E6C1A3DE2}";
            const string strSolutionPersistanceKey = "SampleSourceControlProviderSolutionProperties";
            const string strSolutionUserOptionsKey = "SampleSourceControlProvider";

            int result = 0;

            // Create a solution
            SccProviderService target = GetSccProviderServiceInstance;

            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());

            solution.AddProject(project);

            // Check solution props
            VSQUERYSAVESLNPROPS[] saveSolnProps = new VSQUERYSAVESLNPROPS[1];
            result = sccProvider.QuerySaveSolutionProps(null, saveSolnProps);
            Assert.AreEqual(VSConstants.S_OK, result);
            Assert.AreEqual <VSQUERYSAVESLNPROPS>(VSQUERYSAVESLNPROPS.QSP_HasNoProps, saveSolnProps[0]);

            // Add the solution to source control.
            Hashtable uncontrolled = new Hashtable();

            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);

            // Solution should be dirty now
            result = sccProvider.QuerySaveSolutionProps(null, saveSolnProps);
            Assert.AreEqual(VSConstants.S_OK, result);
            Assert.AreEqual <VSQUERYSAVESLNPROPS>(VSQUERYSAVESLNPROPS.QSP_HasDirtyProps, saveSolnProps[0]);

            // Set the project offline so we'll have something to save in the "suo" stream
            target.ToggleOfflineStatus(project);

            // Force the provider to write the solution info into a stream
            IStream pOptionsStream = new ComStreamFromDataStream(new MemoryStream()) as IStream;

            sccProvider.WriteUserOptions(pOptionsStream, strSolutionUserOptionsKey);
            // Move the stream position to the beginning
            LARGE_INTEGER liOffset;

            liOffset.QuadPart = 0;
            ULARGE_INTEGER[] ulPosition = new ULARGE_INTEGER[1];
            pOptionsStream.Seek(liOffset, 0, ulPosition);

            // Write solution props
            BaseMock propertyBag = MockPropertyBagProvider.GetWritePropertyBag();

            sccProvider.WriteSolutionProps(null, strSolutionPersistanceKey, propertyBag as IPropertyBag);

            // Close the solution to clean up the scc status
            int pfCancel = 0;

            target.OnQueryCloseProject(project, 0, ref pfCancel);
            target.OnQueryCloseSolution(null, ref pfCancel);
            Assert.AreEqual(pfCancel, 0, "Solution close was canceled");
            target.OnBeforeCloseProject(project, 0);
            // Theoretically the project should have called this, but especially after an add to scc, some projects forget to call it
            // target.UnregisterSccProject(project);
            target.OnBeforeCloseSolution(null);
            target.OnAfterCloseSolution(null);

            // Now attempt the "reopen"
            // The solution reads the solution properties
            propertyBag = MockPropertyBagProvider.GetReadPropertyBag();
            sccProvider.ReadSolutionProps(null, null, null, strSolutionPersistanceKey, 1, propertyBag as IPropertyBag);
            // The solution reads the user options from the stream where they were written before
            sccProvider.ReadUserOptions(pOptionsStream, strSolutionUserOptionsKey);
            // Then the projects are opened and register with the provider
            target.RegisterSccProject(project, "Project's location", "AuxPath", Path.GetDirectoryName(project.ProjectFile), strProviderName);
            // solution event fired for this project
            target.OnAfterOpenProject(project, 0);
            // Then solution completes opening
            target.OnAfterOpenSolution(null, 0);

            Assert.IsTrue(target.IsProjectControlled(null), "The solution's controlled status was not correctly persisted or read from property bag");
            Assert.IsTrue(target.IsProjectControlled(project), "The project's controlled status was not correctly set");
            Assert.IsTrue(target.IsProjectOffline(project), "The project's offline status was incorrectly persisted or read from suo stream");
        }
        public void TestOpenCloseControlled()
        {
            const string strProviderName = "Sample Source Control Provider:{B0BAC05D-2000-41D1-A6C3-704E6C1A3DE2}";
            const string strSolutionPersistanceKey = "SampleSourceControlProviderSolutionProperties";
            const string strSolutionUserOptionsKey = "SampleSourceControlProvider";

            int result = 0;

            // Create a solution
            SccProviderService target = GetSccProviderServiceInstance;
            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());
            solution.AddProject(project);

            // Check solution props
            VSQUERYSAVESLNPROPS[] saveSolnProps = new VSQUERYSAVESLNPROPS[1];
            result = sccProvider.QuerySaveSolutionProps(null, saveSolnProps);
            Assert.AreEqual(VSConstants.S_OK, result);
            Assert.AreEqual<VSQUERYSAVESLNPROPS>(VSQUERYSAVESLNPROPS.QSP_HasNoProps, saveSolnProps[0]);

            // Add the solution to source control.
            Hashtable uncontrolled = new Hashtable();
            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);

            // Solution should be dirty now
            result = sccProvider.QuerySaveSolutionProps(null, saveSolnProps);
            Assert.AreEqual(VSConstants.S_OK, result);
            Assert.AreEqual<VSQUERYSAVESLNPROPS>(VSQUERYSAVESLNPROPS.QSP_HasDirtyProps, saveSolnProps[0]);

            // Set the project offline so we'll have something to save in the "suo" stream
            target.ToggleOfflineStatus(project);

            // Force the provider to write the solution info into a stream
            IStream pOptionsStream = new ComStreamFromDataStream(new MemoryStream()) as IStream;
            sccProvider.WriteUserOptions(pOptionsStream, strSolutionUserOptionsKey);
            // Move the stream position to the beginning
            LARGE_INTEGER liOffset;
            liOffset.QuadPart = 0;
            ULARGE_INTEGER[] ulPosition = new ULARGE_INTEGER[1];
            pOptionsStream.Seek(liOffset, 0, ulPosition);

            // Write solution props
            BaseMock propertyBag = MockPropertyBagProvider.GetWritePropertyBag();
            sccProvider.WriteSolutionProps(null, strSolutionPersistanceKey, propertyBag as IPropertyBag);

            // Close the solution to clean up the scc status
            int pfCancel = 0;
            target.OnQueryCloseProject(project, 0, ref pfCancel);
            target.OnQueryCloseSolution(null, ref pfCancel);
            Assert.AreEqual(pfCancel, 0, "Solution close was canceled");
            target.OnBeforeCloseProject(project, 0);
            // Theoretically the project should have called this, but especially after an add to scc, some projects forget to call it
            // target.UnregisterSccProject(project);
            target.OnBeforeCloseSolution(null);
            target.OnAfterCloseSolution(null);

            // Now attempt the "reopen"
            // The solution reads the solution properties
            propertyBag = MockPropertyBagProvider.GetReadPropertyBag();
            sccProvider.ReadSolutionProps(null, null, null, strSolutionPersistanceKey, 1, propertyBag as IPropertyBag);
            // The solution reads the user options from the stream where they were written before
            sccProvider.ReadUserOptions(pOptionsStream, strSolutionUserOptionsKey);
            // Then the projects are opened and register with the provider
            target.RegisterSccProject(project, "Project's location", "AuxPath", Path.GetDirectoryName(project.ProjectFile), strProviderName);
            // solution event fired for this project
            target.OnAfterOpenProject(project, 0);
            // Then solution completes opening
            target.OnAfterOpenSolution(null, 0);

            Assert.IsTrue(target.IsProjectControlled(null), "The solution's controlled status was not correctly persisted or read from property bag");
            Assert.IsTrue(target.IsProjectControlled(project), "The project's controlled status was not correctly set");
            Assert.IsTrue(target.IsProjectOffline(project), "The project's offline status was incorrectly persisted or read from suo stream");
        }