{"action":"created","comment":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/comments/59429273","id":59429273,"diff_hunk":"@@ -66,6 +68,550 @@ public static void VerifyCrlCache()\n             }\n         }\n \n+        [Fact]\n+        public static void X509Store_OpenExisting_Fails()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    // Since the directory was explicitly deleted already, this should fail.\n+                    Assert.Throws<CryptographicException>(\n+                        () => store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly));\n+                });\n+        }\n+\n+        [Fact]\n+        private static void X509Store_AddReadOnly()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var cert = new X509Certificate2(TestData.MsCertificate))\n+                    {\n+                        store.Open(OpenFlags.ReadOnly);\n+\n+                        // Adding a certificate when the store is ReadOnly should fail:\n+                        Assert.Throws<CryptographicException>(() => store.Add(cert));\n+\n+                        // Since we haven't done anything yet, we shouldn't have polluted the hard drive.\n+                        Assert.False(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        private static void X509Store_AddClosed()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var cert = new X509Certificate2(TestData.MsCertificate))\n+                    {\n+                        // Adding a certificate when the store is closed should fail:\n+                        Assert.Throws<CryptographicException>(() => store.Add(cert));\n+\n+                        // Since we haven't done anything yet, we shouldn't have polluted the hard drive.\n+                        Assert.False(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_AddOne()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var cert = new X509Certificate2(TestData.MsCertificate))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(cert);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                        Assert.Equal(1, Directory.GetFiles(storeDirectory).Length);\n+\n+                        X509Certificate2Collection storeCerts = store.Certificates;\n+\n+                        Assert.Equal(1, storeCerts.Count);\n+\n+                        using (X509Certificate2 storeCert = storeCerts[0])\n+                        {\n+                            Assert.Equal(cert, storeCert);\n+                            Assert.NotSame(cert, storeCert);\n+                        }\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_AddOneAfterUpgrade()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var cert = new X509Certificate2(TestData.MsCertificate))\n+                    {\n+                        store.Open(OpenFlags.ReadOnly);\n+\n+                        // Adding a certificate when the store is ReadOnly should fail:\n+                        Assert.Throws<CryptographicException>(() => store.Add(cert));\n+\n+                        // Since we haven't done anything yet, we shouldn't have polluted the hard drive.\n+                        Assert.False(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+\n+                        // Calling Open on an open store changes the access rights:\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(cert);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                        Assert.Equal(1, Directory.GetFiles(storeDirectory).Length);\n+\n+                        X509Certificate2Collection storeCerts = store.Certificates;\n+\n+                        Assert.Equal(1, storeCerts.Count);\n+\n+                        using (X509Certificate2 storeCert = storeCerts[0])\n+                        {\n+                            Assert.Equal(cert, storeCert);\n+                            Assert.NotSame(cert, storeCert);\n+                        }\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_DowngradePermissions()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certA = new X509Certificate2(TestData.MsCertificate))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+                        \n+                        // Ensure that ReadWrite took effect.\n+                        store.Add(certA);\n+\n+                        store.Open(OpenFlags.ReadOnly);\n+\n+                        // Adding a certificate when the store is ReadOnly should fail:\n+                        Assert.Throws<CryptographicException>(() => store.Add(certB));\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        private static void X509Store_AddAfterDispose()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certA = new X509Certificate2(TestData.MsCertificate))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(certA);\n+\n+                        // Dispose returns the store to the pre-opened state.\n+                        store.Dispose();\n+\n+                        // Adding a certificate when the store is closed should fail:\n+                        Assert.Throws<CryptographicException>(() => store.Add(certB));\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_AddAndClear()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var cert = new X509Certificate2(TestData.MsCertificate))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(cert);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                        Assert.Equal(1, Directory.GetFiles(storeDirectory).Length);\n+\n+                        store.Remove(cert);\n+\n+                        // The directory should still exist.\n+                        Assert.True(Directory.Exists(storeDirectory), \"Store Directory Still Exists\");\n+                        Assert.Equal(0, Directory.GetFiles(storeDirectory).Length);\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_AddDuplicate()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var cert = new X509Certificate2(TestData.MsCertificate))\n+                    using (var certClone = new X509Certificate2(cert.RawData))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(cert);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                        Assert.Equal(1, Directory.GetFiles(storeDirectory).Length);\n+\n+                        store.Add(certClone);\n+                        Assert.Equal(1, Directory.GetFiles(storeDirectory).Length);\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_AddTwo()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certA = new X509Certificate2(TestData.MsCertificate))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(certA);\n+                        store.Add(certB);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                        Assert.Equal(2, Directory.GetFiles(storeDirectory).Length);\n+\n+                        X509Certificate2Collection storeCerts = store.Certificates;\n+                        Assert.Equal(2, storeCerts.Count);\n+\n+                        X509Certificate2[] expectedCerts = { certA, certB };\n+\n+                        foreach (X509Certificate2 storeCert in storeCerts)\n+                        {\n+                            Assert.Contains(storeCert, expectedCerts);\n+                            storeCert.Dispose();\n+                        }\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_AddTwo_UpgradePrivateKey()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certAPrivate = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword))\n+                    using (var certAPublic = new X509Certificate2(certAPrivate.RawData))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(certAPublic);\n+                        store.Add(certB);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+\n+                        string[] storeFiles = Directory.GetFiles(storeDirectory);\n+                        Assert.Equal(2, storeFiles.Length);\n+\n+                        X509Certificate2Collection storeCerts = store.Certificates;\n+                        Assert.Equal(2, storeCerts.Count);\n+\n+                        X509Certificate2[] expectedCerts = { certAPublic, certB };\n+\n+                        foreach (X509Certificate2 storeCert in storeCerts)\n+                        {\n+                            Assert.False(storeCert.HasPrivateKey, \"storeCert.HasPrivateKey (before)\");\n+                            storeCert.Dispose();\n+                        }\n+\n+                        store.Add(certAPrivate);\n+                        // It replaces the existing file, the names should be unaffected.\n+                        Assert.Equal(storeFiles, Directory.GetFiles(storeDirectory));\n+\n+                        storeCerts = store.Certificates;\n+                        Assert.Equal(2, storeCerts.Count);\n+\n+                        bool foundCertA = false;\n+\n+                        foreach (X509Certificate2 storeCert in storeCerts)\n+                        {\n+                            // The public instance and private instance are .Equal\n+                            if (storeCert.Equals(certAPublic))\n+                            {\n+                                Assert.True(storeCert.HasPrivateKey, \"storeCert.HasPrivateKey (affected cert)\");\n+                                foundCertA = true;\n+                            }\n+                            else\n+                            {\n+                                Assert.False(storeCert.HasPrivateKey, \"storeCert.HasPrivateKey (other cert)\");\n+                            }\n+\n+                            Assert.Contains(storeCert, expectedCerts);\n+                            storeCert.Dispose();\n+                        }\n+\n+                        Assert.True(foundCertA, \"foundCertA\");\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_AddTwo_UpgradePrivateKey_NoDowngrade()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certAPrivate = new X509Certificate2(TestData.PfxData, TestData.PfxDataPassword))\n+                    using (var certAPublic = new X509Certificate2(certAPrivate.RawData))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(certAPublic);\n+                        store.Add(certB);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+\n+                        X509Certificate2Collection storeCerts = store.Certificates;\n+                        Assert.Equal(2, storeCerts.Count);\n+\n+                        X509Certificate2[] expectedCerts = { certAPublic, certB };\n+\n+                        foreach (X509Certificate2 storeCert in storeCerts)\n+                        {\n+                            Assert.False(storeCert.HasPrivateKey, \"storeCert.HasPrivateKey (before)\");\n+                            Assert.Contains(storeCert, expectedCerts);\n+                            storeCert.Dispose();\n+                        }\n+\n+                        // Add the private (checked in X509Store_AddTwo_UpgradePrivateKey)\n+                        store.Add(certAPrivate);\n+                        // Then add the public again, which shouldn't do anything.\n+                        store.Add(certAPublic);\n+\n+                        storeCerts = store.Certificates;\n+                        Assert.Equal(2, storeCerts.Count);\n+\n+                        bool foundCertA = false;\n+\n+                        foreach (X509Certificate2 storeCert in storeCerts)\n+                        {\n+                            if (storeCert.Equals(certAPublic))\n+                            {\n+                                Assert.True(storeCert.HasPrivateKey, \"storeCert.HasPrivateKey (affected cert)\");\n+                                foundCertA = true;\n+                            }\n+                            else\n+                            {\n+                                Assert.False(storeCert.HasPrivateKey, \"storeCert.HasPrivateKey (other cert)\");\n+                            }\n+\n+                            Assert.Contains(storeCert, expectedCerts);\n+                            storeCert.Dispose();\n+                        }\n+                        \n+                        Assert.True(foundCertA, \"foundCertA\");\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_DistinctCollections()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certA = new X509Certificate2(TestData.MsCertificate))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(certA);\n+                        store.Add(certB);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                        Assert.Equal(2, Directory.GetFiles(storeDirectory).Length);\n+\n+                        X509Certificate2Collection storeCertsA = store.Certificates;\n+                        X509Certificate2Collection storeCertsB = store.Certificates;\n+\n+                        Assert.NotSame(storeCertsA, storeCertsB);\n+                        Assert.Equal(storeCertsA.Count, storeCertsB.Count);\n+\n+                        foreach (X509Certificate2 collACert in storeCertsA)\n+                        {\n+                            int bIndex = storeCertsB.IndexOf(collACert);\n+                            Assert.InRange(bIndex, 0, storeCertsB.Count);\n+\n+                            X509Certificate2 collBCert = storeCertsB[bIndex];\n+                            // Equal is implied by IndexOf working.\n+                            Assert.NotSame(collACert, collBCert);\n+\n+                            storeCertsB.RemoveAt(bIndex);\n+\n+                            collACert.Dispose();\n+                            collBCert.Dispose();\n+                        }\n+                    }\n+                });\n+        }\n+\n+        [Fact]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        private static void X509Store_Add4_Remove1()\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certA = new X509Certificate2(TestData.MsCertificate))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    using (var certBClone = new X509Certificate2(certB.RawData))\n+                    using (var certC = new X509Certificate2(TestData.ECDsa256Certificate))\n+                    using (var certD = new X509Certificate2(TestData.MicrosoftDotComRootBytes))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+                        \n+                        store.Add(certA);\n+                        store.Add(certB);\n+                        store.Add(certC);\n+                        store.Add(certD);\n+\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+                        Assert.Equal(4, Directory.GetFiles(storeDirectory).Length);\n+\n+                        X509Certificate2[] expectedCerts = { certA, certB, certC, certD };\n+                        X509Certificate2Collection storeCerts = store.Certificates;\n+                        Assert.Equal(4, storeCerts.Count);\n+\n+                        foreach (X509Certificate2 storeCert in storeCerts)\n+                        {\n+                            Assert.Contains(storeCert, expectedCerts);\n+                            storeCert.Dispose();\n+                        }\n+\n+                        store.Remove(certBClone);\n+                        Assert.Equal(3, Directory.GetFiles(storeDirectory).Length);\n+\n+                        expectedCerts = new[] { certA, certC, certD };\n+                        storeCerts = store.Certificates;\n+                        Assert.Equal(3, storeCerts.Count);\n+\n+                        foreach (X509Certificate2 storeCert in storeCerts)\n+                        {\n+                            Assert.Contains(storeCert, expectedCerts);\n+                            storeCert.Dispose();\n+                        }\n+                    }\n+                });\n+        }\n+\n+        [Theory]\n+        [OuterLoop(/* Alters user/machine state */)]\n+        [InlineData(false)]\n+        [InlineData(true)]\n+        private static void X509Store_MultipleObjects(bool matchCase)\n+        {\n+            RunX509StoreTest(\n+                (store, storeDirectory) =>\n+                {\n+                    using (var certA = new X509Certificate2(TestData.MsCertificate))\n+                    using (var certB = new X509Certificate2(TestData.DssCer))\n+                    using (var certC = new X509Certificate2(TestData.ECDsa256Certificate))\n+                    using (var certD = new X509Certificate2(TestData.MicrosoftDotComRootBytes))\n+                    {\n+                        store.Open(OpenFlags.ReadWrite);\n+\n+                        store.Add(certA);\n+                        store.Add(certB);\n+                        Assert.True(Directory.Exists(storeDirectory), \"Directory.Exists(storeDirectory)\");\n+\n+                        string newName = store.Name;\n+\n+                        if (!matchCase)\n+                        {\n+                            newName = newName.ToUpperInvariant();\n+                            Assert.NotEqual(store.Name, newName);\n+                        }\n+\n+                        using (X509Store storeClone = new X509Store(newName, store.Location))\n+                        {\n+                            storeClone.Open(OpenFlags.ReadWrite);\n+\n+                            X509Certificate2Collection storeCerts = store.Certificates;\n+                            X509Certificate2Collection storeCloneCerts = storeClone.Certificates;\n+\n+                            Assert.Equal(\n+                                storeCerts.OfType<X509Certificate2>(),\n+                                storeCloneCerts.OfType<X509Certificate2>());\n+\n+                            store.Add(certC);\n+\n+                            // The object was added to store, but should show up in both objects\n+                            // after re-reading the Certificates property\n+                            storeCerts = store.Certificates;\n+                            storeCloneCerts = storeClone.Certificates;\n+\n+                            Assert.Equal(\n+                                storeCerts.OfType<X509Certificate2>(),\n+                                storeCloneCerts.OfType<X509Certificate2>());\n+\n+                            // Now add one to storeClone to prove bidirectionality.\n+                            storeClone.Add(certD);\n+                            storeCerts = store.Certificates;\n+                            storeCloneCerts = storeClone.Certificates;\n+\n+                            Assert.Equal(\n+                                storeCerts.OfType<X509Certificate2>(),\n+                                storeCloneCerts.OfType<X509Certificate2>());\n+                        }\n+                    }\n+                });\n+        }\n+        \n+        private static void RunX509StoreTest(Action<X509Store, string> testAction)\n+        {\n+            string storesDirectory = PersistedFiles.GetUserFeatureDirectory(\"cryptography\", \"x509stores\");\n+            string storeName = \"TestStore\" + Guid.NewGuid().ToString(\"N\");\n+            string storeDirectory = Path.Combine(storesDirectory, storeName.ToLowerInvariant());\n+\n+            if (Directory.Exists(storeDirectory))\n+            {\n+                Directory.Delete(storeDirectory, true);\n+            }","path":"src/System.Security.Cryptography.X509Certificates/tests/X509FilesystemTests.Unix.cs","position":533,"original_position":533,"commit_id":"a775727fab00372f7d1b88d19867f3f1bfd3a3db","original_commit_id":"a775727fab00372f7d1b88d19867f3f1bfd3a3db","user":{"login":"bartonjs","id":10642668,"avatar_url":"https://avatars.githubusercontent.com/u/10642668?v=3","gravatar_id":"","url":"https://api.github.com/users/bartonjs","html_url":"https://github.com/bartonjs","followers_url":"https://api.github.com/users/bartonjs/followers","following_url":"https://api.github.com/users/bartonjs/following{/other_user}","gists_url":"https://api.github.com/users/bartonjs/gists{/gist_id}","starred_url":"https://api.github.com/users/bartonjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartonjs/subscriptions","organizations_url":"https://api.github.com/users/bartonjs/orgs","repos_url":"https://api.github.com/users/bartonjs/repos","events_url":"https://api.github.com/users/bartonjs/events{/privacy}","received_events_url":"https://api.github.com/users/bartonjs/received_events","type":"User","site_admin":false},"body":"As long as Guid.NewGuid is working there's very little chance that this will stomp over any existing resources.  But since I was going to assert that the directory didn't exist after failed Add calls, I wanted to make sure that was the case.","created_at":"2016-04-12T18:33:53Z","updated_at":"2016-04-12T18:33:53Z","html_url":"https://github.com/dotnet/corefx/pull/7655#discussion_r59429273","pull_request_url":"https://api.github.com/repos/dotnet/corefx/pulls/7655","_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments/59429273"},"html":{"href":"https://github.com/dotnet/corefx/pull/7655#discussion_r59429273"},"pull_request":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7655"}}},"pull_request":{"url":"https://api.github.com/repos/dotnet/corefx/pulls/7655","id":66039916,"html_url":"https://github.com/dotnet/corefx/pull/7655","diff_url":"https://github.com/dotnet/corefx/pull/7655.diff","patch_url":"https://github.com/dotnet/corefx/pull/7655.patch","issue_url":"https://api.github.com/repos/dotnet/corefx/issues/7655","number":7655,"state":"open","locked":false,"title":"Remove FileSystemWatcher dependency from Unix X509Store","user":{"login":"bartonjs","id":10642668,"avatar_url":"https://avatars.githubusercontent.com/u/10642668?v=3","gravatar_id":"","url":"https://api.github.com/users/bartonjs","html_url":"https://github.com/bartonjs","followers_url":"https://api.github.com/users/bartonjs/followers","following_url":"https://api.github.com/users/bartonjs/following{/other_user}","gists_url":"https://api.github.com/users/bartonjs/gists{/gist_id}","starred_url":"https://api.github.com/users/bartonjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartonjs/subscriptions","organizations_url":"https://api.github.com/users/bartonjs/orgs","repos_url":"https://api.github.com/users/bartonjs/repos","events_url":"https://api.github.com/users/bartonjs/events{/privacy}","received_events_url":"https://api.github.com/users/bartonjs/received_events","type":"User","site_admin":false},"body":"The original impetus for change was to remove the FileSystemWatcher dependency for the Unix implementation of X509Store.  Since changes were being made, some tests were finally added to OuterLoop (since it involves making state changes on the filesystem).  This uncovered an issue that creating new stores fails due to the directory permissions check being overly restrictive (in a way that we explicitly concluded it wasn't doing at the time of the change).\r\n\r\nSo, with the two commits:\r\n* Creating new stores works again\r\n* There are a lot of X509Store tests on Unix\r\n* The FSW dependency is removed, and all the associated caching and cache purge logic.\r\n\r\nSo, this reacts to #6797, fixes #6618, and fixes #3374.\r\n\r\ncc: @stephentoub @weshaggard @AtsushiKan","created_at":"2016-04-11T18:30:18Z","updated_at":"2016-04-12T18:33:53Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ec8b5043d88ed830969dbd03abcf31ea54410ead","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/dotnet/corefx/pulls/7655/commits","review_comments_url":"https://api.github.com/repos/dotnet/corefx/pulls/7655/comments","review_comment_url":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dotnet/corefx/issues/7655/comments","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/a775727fab00372f7d1b88d19867f3f1bfd3a3db","head":{"label":"bartonjs:unix_x509store_nofsw","ref":"unix_x509store_nofsw","sha":"a775727fab00372f7d1b88d19867f3f1bfd3a3db","user":{"login":"bartonjs","id":10642668,"avatar_url":"https://avatars.githubusercontent.com/u/10642668?v=3","gravatar_id":"","url":"https://api.github.com/users/bartonjs","html_url":"https://github.com/bartonjs","followers_url":"https://api.github.com/users/bartonjs/followers","following_url":"https://api.github.com/users/bartonjs/following{/other_user}","gists_url":"https://api.github.com/users/bartonjs/gists{/gist_id}","starred_url":"https://api.github.com/users/bartonjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartonjs/subscriptions","organizations_url":"https://api.github.com/users/bartonjs/orgs","repos_url":"https://api.github.com/users/bartonjs/repos","events_url":"https://api.github.com/users/bartonjs/events{/privacy}","received_events_url":"https://api.github.com/users/bartonjs/received_events","type":"User","site_admin":false},"repo":{"id":29888389,"name":"corefx","full_name":"bartonjs/corefx","owner":{"login":"bartonjs","id":10642668,"avatar_url":"https://avatars.githubusercontent.com/u/10642668?v=3","gravatar_id":"","url":"https://api.github.com/users/bartonjs","html_url":"https://github.com/bartonjs","followers_url":"https://api.github.com/users/bartonjs/followers","following_url":"https://api.github.com/users/bartonjs/following{/other_user}","gists_url":"https://api.github.com/users/bartonjs/gists{/gist_id}","starred_url":"https://api.github.com/users/bartonjs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bartonjs/subscriptions","organizations_url":"https://api.github.com/users/bartonjs/orgs","repos_url":"https://api.github.com/users/bartonjs/repos","events_url":"https://api.github.com/users/bartonjs/events{/privacy}","received_events_url":"https://api.github.com/users/bartonjs/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/bartonjs/corefx","description":"This repository contains the foundational libraries that make up the .NET Core development stack.","fork":true,"url":"https://api.github.com/repos/bartonjs/corefx","forks_url":"https://api.github.com/repos/bartonjs/corefx/forks","keys_url":"https://api.github.com/repos/bartonjs/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/bartonjs/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/bartonjs/corefx/teams","hooks_url":"https://api.github.com/repos/bartonjs/corefx/hooks","issue_events_url":"https://api.github.com/repos/bartonjs/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/bartonjs/corefx/events","assignees_url":"https://api.github.com/repos/bartonjs/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/bartonjs/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/bartonjs/corefx/tags","blobs_url":"https://api.github.com/repos/bartonjs/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/bartonjs/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/bartonjs/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/bartonjs/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/bartonjs/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/bartonjs/corefx/languages","stargazers_url":"https://api.github.com/repos/bartonjs/corefx/stargazers","contributors_url":"https://api.github.com/repos/bartonjs/corefx/contributors","subscribers_url":"https://api.github.com/repos/bartonjs/corefx/subscribers","subscription_url":"https://api.github.com/repos/bartonjs/corefx/subscription","commits_url":"https://api.github.com/repos/bartonjs/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/bartonjs/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/bartonjs/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/bartonjs/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/bartonjs/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/bartonjs/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/bartonjs/corefx/merges","archive_url":"https://api.github.com/repos/bartonjs/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/bartonjs/corefx/downloads","issues_url":"https://api.github.com/repos/bartonjs/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/bartonjs/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/bartonjs/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/bartonjs/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/bartonjs/corefx/labels{/name}","releases_url":"https://api.github.com/repos/bartonjs/corefx/releases{/id}","deployments_url":"https://api.github.com/repos/bartonjs/corefx/deployments","created_at":"2015-01-26T23:55:53Z","updated_at":"2016-01-18T16:14:34Z","pushed_at":"2016-04-12T15:03:15Z","git_url":"git://github.com/bartonjs/corefx.git","ssh_url":"git@github.com:bartonjs/corefx.git","clone_url":"https://github.com/bartonjs/corefx.git","svn_url":"https://github.com/bartonjs/corefx","homepage":"","size":63371,"stargazers_count":0,"watchers_count":0,"language":"C#","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dotnet:master","ref":"master","sha":"ccfa9c41cf7fc1a434cebc90ee1bb5abfa29966c","user":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"repo":{"id":26295345,"name":"corefx","full_name":"dotnet/corefx","owner":{"login":"dotnet","id":9141961,"avatar_url":"https://avatars.githubusercontent.com/u/9141961?v=3","gravatar_id":"","url":"https://api.github.com/users/dotnet","html_url":"https://github.com/dotnet","followers_url":"https://api.github.com/users/dotnet/followers","following_url":"https://api.github.com/users/dotnet/following{/other_user}","gists_url":"https://api.github.com/users/dotnet/gists{/gist_id}","starred_url":"https://api.github.com/users/dotnet/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dotnet/subscriptions","organizations_url":"https://api.github.com/users/dotnet/orgs","repos_url":"https://api.github.com/users/dotnet/repos","events_url":"https://api.github.com/users/dotnet/events{/privacy}","received_events_url":"https://api.github.com/users/dotnet/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dotnet/corefx","description":"This repo contains the .NET Core foundational libraries, called CoreFX. It includes classes for collections, file systems, console, XML, async and many others.","fork":false,"url":"https://api.github.com/repos/dotnet/corefx","forks_url":"https://api.github.com/repos/dotnet/corefx/forks","keys_url":"https://api.github.com/repos/dotnet/corefx/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dotnet/corefx/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dotnet/corefx/teams","hooks_url":"https://api.github.com/repos/dotnet/corefx/hooks","issue_events_url":"https://api.github.com/repos/dotnet/corefx/issues/events{/number}","events_url":"https://api.github.com/repos/dotnet/corefx/events","assignees_url":"https://api.github.com/repos/dotnet/corefx/assignees{/user}","branches_url":"https://api.github.com/repos/dotnet/corefx/branches{/branch}","tags_url":"https://api.github.com/repos/dotnet/corefx/tags","blobs_url":"https://api.github.com/repos/dotnet/corefx/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dotnet/corefx/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dotnet/corefx/git/refs{/sha}","trees_url":"https://api.github.com/repos/dotnet/corefx/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dotnet/corefx/statuses/{sha}","languages_url":"https://api.github.com/repos/dotnet/corefx/languages","stargazers_url":"https://api.github.com/repos/dotnet/corefx/stargazers","contributors_url":"https://api.github.com/repos/dotnet/corefx/contributors","subscribers_url":"https://api.github.com/repos/dotnet/corefx/subscribers","subscription_url":"https://api.github.com/repos/dotnet/corefx/subscription","commits_url":"https://api.github.com/repos/dotnet/corefx/commits{/sha}","git_commits_url":"https://api.github.com/repos/dotnet/corefx/git/commits{/sha}","comments_url":"https://api.github.com/repos/dotnet/corefx/comments{/number}","issue_comment_url":"https://api.github.com/repos/dotnet/corefx/issues/comments{/number}","contents_url":"https://api.github.com/repos/dotnet/corefx/contents/{+path}","compare_url":"https://api.github.com/repos/dotnet/corefx/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dotnet/corefx/merges","archive_url":"https://api.github.com/repos/dotnet/corefx/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dotnet/corefx/downloads","issues_url":"https://api.github.com/repos/dotnet/corefx/issues{/number}","pulls_url":"https://api.github.com/repos/dotnet/corefx/pulls{/number}","milestones_url":"https://api.github.com/repos/dotnet/corefx/milestones{/number}","notifications_url":"https://api.github.com/repos/dotnet/corefx/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dotnet/corefx/labels{/name}","releases_url":"https://api.github.com/repos/dotnet/corefx/releases{/id}","deployments_url":"https://api.github.com/repos/dotnet/corefx/deployments","created_at":"2014-11-06T23:42:48Z","updated_at":"2016-04-12T17:06:08Z","pushed_at":"2016-04-12T18:30:43Z","git_url":"git://github.com/dotnet/corefx.git","ssh_url":"git@github.com:dotnet/corefx.git","clone_url":"https://github.com/dotnet/corefx.git","svn_url":"https://github.com/dotnet/corefx","homepage":"http://dotnet.github.io/","size":86229,"stargazers_count":9485,"watchers_count":9485,"language":"C#","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":2242,"mirror_url":null,"open_issues_count":946,"forks":2242,"open_issues":946,"watchers":9485,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7655"},"html":{"href":"https://github.com/dotnet/corefx/pull/7655"},"issue":{"href":"https://api.github.com/repos/dotnet/corefx/issues/7655"},"comments":{"href":"https://api.github.com/repos/dotnet/corefx/issues/7655/comments"},"review_comments":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7655/comments"},"review_comment":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dotnet/corefx/pulls/7655/commits"},"statuses":{"href":"https://api.github.com/repos/dotnet/corefx/statuses/a775727fab00372f7d1b88d19867f3f1bfd3a3db"}}}}