text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Security.Cryptography.Xml;
using System.Security.Cryptography.X509Certificates;
using Xunit;

using Test.Cryptography;
using System.Security.Cryptography.Pkcs.Tests;

namespace System.Security.Cryptography.Pkcs.EnvelopedCmsTests.Tests
{
    public static partial class EdgeCasesTests
    {
        public static bool SupportsRc4 { get; } = ContentEncryptionAlgorithmTests.SupportsRc4;

        [Fact]
        [OuterLoop(/* Leaks key on disk if interrupted */)]
        public static void ImportEdgeCase()
        {
            //
            // Pfx's imported into a certificate collection propagate their "delete on Dispose" behavior to its cloned instances:
            // a subtle difference from Pfx's created using the X509Certificate2 constructor that can lead to premature or
            // double key deletion. Since EnvelopeCms.Decrypt() has no legitimate reason to clone the extraStore certs, this shouldn't
            // be a problem, but this test will verify that it isn't.
            //

            byte[] encodedMessage =
                ("3082010c06092a864886f70d010703a081fe3081fb0201003181c83081c5020100302e301a311830160603550403130f5253"
                + "414b65795472616e7366657231021031d935fb63e8cfab48a0bf7b397b67c0300d06092a864886f70d01010105000481805e"
                + "bb2d08773594be9ec5d30c0707cf339f2b982a4f0797b74d520a0c973d668a9a6ad9d28066ef36e5b5620fef67f4d79ee50c"
                + "25eb999f0c656548347d5676ac4b779f8fce2b87e6388fbe483bb0fcf78ab1f1ff29169600401fded7b2803a0bf96cc160c4"
                + "96726216e986869eed578bda652855c85604a056201538ee56b6c4302b06092a864886f70d010701301406082a864886f70d"
                + "030704083adadf63cd297a86800835edc437e31d0b70").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.LoadPfxUsingCollectionImport())
            {
                X509Certificate2Collection extraStore = new X509Certificate2Collection(cert);
                ecms.Decrypt(extraStore);

                byte[] expectedContent = { 1, 2, 3 };
                ContentInfo contentInfo = ecms.ContentInfo;
                Assert.Equal<byte>(expectedContent, contentInfo.Content);
            }
        }

        [Fact]
        [OuterLoop(/* Leaks key on disk if interrupted */)]
        public static void ImportEdgeCaseSki()
        {
            byte[] encodedMessage =
                ("3081f206092a864886f70d010703a081e43081e10201023181ae3081ab0201028014f2008aa9fa3742e8370cb1674ce1d158"
                + "2921dcc3300d06092a864886f70d01010105000481804336e978bc72ba2f5264cd854867fac438f36f2b3df6004528f2df83"
                + "4fb2113d6f7c07667e7296b029756222d6ced396a8fffed32be838eec7f2e54b9467fa80f85d097f7d1f0fbde57e07ab3d46"
                + "a60b31f37ef9844dcab2a8eef4fec5579fac5ec1e7ee82409898e17d30c3ac1a407fca15d23c9df2904a707294d78d4300ba"
                + "302b06092a864886f70d010701301406082a864886f70d03070408355c596e3e8540608008f1f811e862e51bbd").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.LoadPfxUsingCollectionImport())
            {
                X509Certificate2Collection extraStore = new X509Certificate2Collection(cert);
                ecms.Decrypt(extraStore);

                byte[] expectedContent = { 1, 2, 3 };
                ContentInfo contentInfo = ecms.ContentInfo;
                Assert.Equal<byte>(new byte[] { 1, 2, 3 }, contentInfo.Content);
                Assert.Equal<byte>(expectedContent, contentInfo.Content);
            }
        }

        private static X509Certificate2 LoadPfxUsingCollectionImport(this CertLoader certLoader)
        {
            byte[] pfxData = certLoader.PfxData;
            string password = certLoader.Password;
            X509Certificate2Collection collection = new X509Certificate2Collection();
            collection.Import(pfxData, password, X509KeyStorageFlags.DefaultKeySet);
            Assert.Equal(1, collection.Count);
            return collection[0];
        }

        [Fact]
        public static void ZeroLengthContextUntagged_FixedValue()
        {
            // This test ensures that we can handle when the enveloped message has no content inside. This test differs
            // from "ZeroLengthContent_FixedValue" in that it doesn't have a context specific [0] in the EncryptedContentInfo
            // section of the DER encoding of the message.
            // EncryptedContentInfo ::= SEQUENCE {
            //      contentType ContentType,
            //      contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
            //      encryptedContent[0] IMPLICIT EncryptedContent OPTIONAL }
            // The input was created with ASN1 editor and verified with .NET framework. It's an enveloped message, version 0,
            // with one Key Transport recipient and holds data encrypted with 3DES.
            byte[] content =
                 ("3082010206092A864886F70D010703A081F43081F10201003181C83081C5020100302E301A311830160603550403130F"
                 + "5253414B65795472616E7366657231021031D935FB63E8CFAB48A0BF7B397B67C0300D06092A864886F70D0101010500"
                 + "04818009C16B674495C2C3D4763189C3274CF7A9142FBEEC8902ABDC9CE29910D541DF910E029A31443DC9A9F3B05F02"
                 + "DA1C38478C400261C734D6789C4197C20143C4312CEAA99ECB1849718326D4FC3B7FBB2D1D23281E31584A63E99F2C17"
                 + "132BCD8EDDB632967125CD0A4BAA1EFA8CE4C855F7C093339211BDF990CEF5CCE6CD74302106092A864886F70D010701"
                 + "301406082A864886F70D03070408779B3DE045826B18").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(content);

            int expected = PlatformDetection.IsFullFramework ? 6 : 0; // Desktop bug gives 6
            Assert.Equal(expected, ecms.ContentInfo.Content.Length);
            Assert.Equal(Oids.Pkcs7Data, ecms.ContentInfo.ContentType.Value);
        }

        [Fact]
        [OuterLoop(/* Leaks key on disk if interrupted */)]
        [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework, "Desktop rejects zero length content: corefx#18724")]
        public static void ZeroLengthContent_RoundTrip()
        {
            ContentInfo contentInfo = new ContentInfo(Array.Empty<byte>());
            EnvelopedCms ecms = new EnvelopedCms(contentInfo);
            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate())
            {
                CmsRecipient cmsRecipient = new CmsRecipient(cert);
                ecms.Encrypt(cmsRecipient);
            }
            byte[] encodedMessage = ecms.Encode();
            ValidateZeroLengthContent(encodedMessage);
        }

        [Fact]
        [OuterLoop(/* Leaks key on disk if interrupted */)]
        public static void ZeroLengthContent_FixedValue()
        {
            byte[] encodedMessage =
                 ("3082010406092a864886f70d010703a081f63081f30201003181c83081c5020100302e301a311830160603550403130f5253"
                + "414b65795472616e7366657231021031d935fb63e8cfab48a0bf7b397b67c0300d06092a864886f70d010101050004818009"
                + "c16b674495c2c3d4763189c3274cf7a9142fbeec8902abdc9ce29910d541df910e029a31443dc9a9f3b05f02da1c38478c40"
                + "0261c734d6789c4197c20143c4312ceaa99ecb1849718326d4fc3b7fbb2d1d23281e31584a63e99f2c17132bcd8eddb63296"
                + "7125cd0a4baa1efa8ce4c855f7c093339211bdf990cef5cce6cd74302306092a864886f70d010701301406082a864886f70d"
                + "03070408779b3de045826b188000").HexToByteArray();
            ValidateZeroLengthContent(encodedMessage);
        }

        [ConditionalFact(nameof(SupportsRc4))]
        [OuterLoop(/* Leaks key on disk if interrupted */)]
        public static void Rc4AndCngWrappersDontMixTest()
        {
            //
            // Combination of RC4 over a CAPI certificate.
            //
            //  This works as long as the PKCS implementation opens the cert using CAPI. If he creates a CNG wrapper handle (by passing CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG),
            //  the test fails with a NOTSUPPORTED crypto exception inside Decrypt(). The same happens if the key is genuinely CNG.
            //

            byte[] content = { 6, 3, 128, 33, 44 };
            AlgorithmIdentifier rc4 = new AlgorithmIdentifier(new Oid(Oids.Rc4));

            EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(content), rc4);
            CmsRecipientCollection recipients = new CmsRecipientCollection(new CmsRecipient(Certificates.RSAKeyTransferCapi1.GetCertificate()));
            ecms.Encrypt(recipients);
            byte[] encodedMessage = ecms.Encode();

            ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);

            // In order to actually use the CAPI version of the key, perphemeral loading must be specified.
            using (X509Certificate2 cert = Certificates.RSAKeyTransferCapi1.CloneAsPerphemeralLoader().TryGetCertificateWithPrivateKey())
            {
                if (cert == null)
                    return; // Sorry - CertLoader is not configured to load certs with private keys - we've tested as much as we can.

                X509Certificate2Collection extraStore = new X509Certificate2Collection();
                extraStore.Add(cert);
                ecms.Decrypt(extraStore);
            }

            ContentInfo contentInfo = ecms.ContentInfo;
            Assert.Equal<byte>(content, contentInfo.Content);
        }

        private static void ValidateZeroLengthContent(byte[] encodedMessage)
        {
            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);
            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.TryGetCertificateWithPrivateKey())
            {
                if (cert == null)
                    return;
                X509Certificate2Collection extraStore = new X509Certificate2Collection(cert);
                ecms.Decrypt(extraStore);
                ContentInfo contentInfo = ecms.ContentInfo;
                byte[] content = contentInfo.Content;

                int expected = PlatformDetection.IsFullFramework ? 6 : 0; // Desktop bug gives 6
                Assert.Equal(expected, content.Length);
            }
        }

        [Fact]
        public static void ReuseEnvelopeCmsEncodeThenDecode()
        {
            // Test ability to encrypt, encode and decode all in one EnvelopedCms instance.

            ContentInfo contentInfo = new ContentInfo(new byte[] { 1, 2, 3 });
            EnvelopedCms ecms = new EnvelopedCms(contentInfo);
            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate())
            {
                CmsRecipient cmsRecipient = new CmsRecipient(cert);
                ecms.Encrypt(cmsRecipient);
            }

            byte[] encodedMessage = ecms.Encode();
            ecms.Decode(encodedMessage);

            RecipientInfoCollection recipients = ecms.RecipientInfos;
            Assert.Equal(1, recipients.Count);
            RecipientInfo recipientInfo = recipients[0];
            KeyTransRecipientInfo recipient = recipientInfo as KeyTransRecipientInfo;
            Assert.NotNull(recipientInfo);

            SubjectIdentifier subjectIdentifier = recipient.RecipientIdentifier;
            object value = subjectIdentifier.Value;
            Assert.True(value is X509IssuerSerial);
            X509IssuerSerial xis = (X509IssuerSerial)value;
            Assert.Equal("CN=RSAKeyTransfer1", xis.IssuerName);
            Assert.Equal("31D935FB63E8CFAB48A0BF7B397B67C0", xis.SerialNumber);
        }

        [Fact]
        public static void ReuseEnvelopeCmsDecodeThenEncode()
        {
            byte[] encodedMessage =
                ("3082010c06092a864886f70d010703a081fe3081fb0201003181c83081c5020100302e301a311830160603550403130f5253"
                + "414b65795472616e7366657231021031d935fb63e8cfab48a0bf7b397b67c0300d06092a864886f70d01010105000481805e"
                + "bb2d08773594be9ec5d30c0707cf339f2b982a4f0797b74d520a0c973d668a9a6ad9d28066ef36e5b5620fef67f4d79ee50c"
                + "25eb999f0c656548347d5676ac4b779f8fce2b87e6388fbe483bb0fcf78ab1f1ff29169600401fded7b2803a0bf96cc160c4"
                + "96726216e986869eed578bda652855c85604a056201538ee56b6c4302b06092a864886f70d010701301406082a864886f70d"
                + "030704083adadf63cd297a86800835edc437e31d0b70").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);
            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate())
            {
                CmsRecipient cmsRecipient = new CmsRecipient(cert);
                ecms.Encrypt(cmsRecipient);
            }

            encodedMessage = ecms.Encode();
            ecms.Decode(encodedMessage);

            RecipientInfoCollection recipients = ecms.RecipientInfos;
            Assert.Equal(1, recipients.Count);
            RecipientInfo recipientInfo = recipients[0];
            KeyTransRecipientInfo recipient = recipientInfo as KeyTransRecipientInfo;
            Assert.NotNull(recipientInfo);

            SubjectIdentifier subjectIdentifier = recipient.RecipientIdentifier;
            object value = subjectIdentifier.Value;
            Assert.True(value is X509IssuerSerial);
            X509IssuerSerial xis = (X509IssuerSerial)value;
            Assert.Equal("CN=RSAKeyTransfer1", xis.IssuerName);
            Assert.Equal("31D935FB63E8CFAB48A0BF7B397B67C0", xis.SerialNumber);
        }

        [Fact]
        public static void EnvelopedCmsNullContent()
        {
            object ignore;
            Assert.Throws<ArgumentNullException>(() => ignore = new EnvelopedCms(null));
            Assert.Throws<ArgumentNullException>(() => ignore = new EnvelopedCms(null, new AlgorithmIdentifier(new Oid(Oids.TripleDesCbc))));
        }

        [Fact]
        public static void EnvelopedCmsNullAlgorithm()
        {
            object ignore;
            ContentInfo contentInfo = new ContentInfo(new byte[3]);
            Assert.Throws<ArgumentNullException>(() => ignore = new EnvelopedCms(contentInfo, null));
        }

        [Fact]
        public static void EnvelopedCmsEncryptWithNullRecipient()
        {
            EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(new byte[3]));
            Assert.Throws<ArgumentNullException>(() => ecms.Encrypt((CmsRecipient)null));
        }

        [Fact]
        public static void EnvelopedCmsEncryptWithNullRecipients()
        {
            EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(new byte[3]));
            Assert.Throws<ArgumentNullException>(() => ecms.Encrypt((CmsRecipientCollection)null));
        }

        [Fact]
        // On the desktop, this throws up a UI for the user to select a recipient. We don't support that.
        [SkipOnTargetFramework(TargetFrameworkMonikers.NetFramework)]
        public static void EnvelopedCmsEncryptWithZeroRecipients()
        {
            EnvelopedCms ecms = new EnvelopedCms(new ContentInfo(new byte[3]));
            Assert.Throws<PlatformNotSupportedException>(() => ecms.Encrypt(new CmsRecipientCollection()));
        }

        [Fact]
        public static void EnvelopedCmsNullDecode()
        {
            EnvelopedCms ecms = new EnvelopedCms();
            Assert.Throws<ArgumentNullException>(() => ecms.Decode(null));
        }

        [Fact]
        public static void EnvelopedCmsDecryptNullary()
        {
            byte[] encodedMessage =
                ("3082010c06092a864886f70d010703a081fe3081fb0201003181c83081c5020100302e301a311830160603550403130f5253"
                + "414b65795472616e7366657231021031d935fb63e8cfab48a0bf7b397b67c0300d06092a864886f70d01010105000481805e"
                + "bb2d08773594be9ec5d30c0707cf339f2b982a4f0797b74d520a0c973d668a9a6ad9d28066ef36e5b5620fef67f4d79ee50c"
                + "25eb999f0c656548347d5676ac4b779f8fce2b87e6388fbe483bb0fcf78ab1f1ff29169600401fded7b2803a0bf96cc160c4"
                + "96726216e986869eed578bda652855c85604a056201538ee56b6c4302b06092a864886f70d010701301406082a864886f70d"
                + "030704083adadf63cd297a86800835edc437e31d0b70").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);
            Assert.ThrowsAny<CryptographicException>(() => ecms.Decrypt());
        }

        [Fact]
        public static void EnvelopedCmsDecryptNullRecipient()
        {
            byte[] encodedMessage =
                ("3082010c06092a864886f70d010703a081fe3081fb0201003181c83081c5020100302e301a311830160603550403130f5253"
                + "414b65795472616e7366657231021031d935fb63e8cfab48a0bf7b397b67c0300d06092a864886f70d01010105000481805e"
                + "bb2d08773594be9ec5d30c0707cf339f2b982a4f0797b74d520a0c973d668a9a6ad9d28066ef36e5b5620fef67f4d79ee50c"
                + "25eb999f0c656548347d5676ac4b779f8fce2b87e6388fbe483bb0fcf78ab1f1ff29169600401fded7b2803a0bf96cc160c4"
                + "96726216e986869eed578bda652855c85604a056201538ee56b6c4302b06092a864886f70d010701301406082a864886f70d"
                + "030704083adadf63cd297a86800835edc437e31d0b70").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);
            RecipientInfo recipientInfo = null;
            X509Certificate2Collection extraStore = new X509Certificate2Collection();
            Assert.Throws<ArgumentNullException>(() => ecms.Decrypt(recipientInfo));
            Assert.Throws<ArgumentNullException>(() => ecms.Decrypt(recipientInfo, extraStore));
        }

        [Fact]
        public static void EnvelopedCmsDecryptNullExtraStore()
        {
            byte[] encodedMessage =
                ("3082010c06092a864886f70d010703a081fe3081fb0201003181c83081c5020100302e301a311830160603550403130f5253"
                + "414b65795472616e7366657231021031d935fb63e8cfab48a0bf7b397b67c0300d06092a864886f70d01010105000481805e"
                + "bb2d08773594be9ec5d30c0707cf339f2b982a4f0797b74d520a0c973d668a9a6ad9d28066ef36e5b5620fef67f4d79ee50c"
                + "25eb999f0c656548347d5676ac4b779f8fce2b87e6388fbe483bb0fcf78ab1f1ff29169600401fded7b2803a0bf96cc160c4"
                + "96726216e986869eed578bda652855c85604a056201538ee56b6c4302b06092a864886f70d010701301406082a864886f70d"
                + "030704083adadf63cd297a86800835edc437e31d0b70").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);
            RecipientInfo recipientInfo = ecms.RecipientInfos[0];
            X509Certificate2Collection extraStore = null;
            Assert.Throws<ArgumentNullException>(() => ecms.Decrypt(extraStore));
            Assert.Throws<ArgumentNullException>(() => ecms.Decrypt(recipientInfo, extraStore));
        }

        [Fact]
        [OuterLoop(/* Leaks key on disk if interrupted */)]
        public static void EnvelopedCmsDecryptWithoutMatchingCert()
        {
            // You don't have the private key? No message for you.

            // This is the private key that "we don't have." We want to force it to load anyway, though, to trigger
            // the "fail the test due to bad machine config" exception if someone left this cert in the MY store check.
            using (X509Certificate2 ignore = Certificates.RSAKeyTransfer1.TryGetCertificateWithPrivateKey())
            { }

            byte[] encodedMessage =
                ("3082010c06092a864886f70d010703a081fe3081fb0201003181c83081c5020100302e301a311830160603550403130f5253"
                + "414b65795472616e7366657231021031d935fb63e8cfab48a0bf7b397b67c0300d06092a864886f70d01010105000481805e"
                + "bb2d08773594be9ec5d30c0707cf339f2b982a4f0797b74d520a0c973d668a9a6ad9d28066ef36e5b5620fef67f4d79ee50c"
                + "25eb999f0c656548347d5676ac4b779f8fce2b87e6388fbe483bb0fcf78ab1f1ff29169600401fded7b2803a0bf96cc160c4"
                + "96726216e986869eed578bda652855c85604a056201538ee56b6c4302b06092a864886f70d010701301406082a864886f70d"
                + "030704083adadf63cd297a86800835edc437e31d0b70").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);
            RecipientInfo recipientInfo = ecms.RecipientInfos[0];
            X509Certificate2Collection extraStore = new X509Certificate2Collection();
            Assert.ThrowsAny<CryptographicException>(() => ecms.Decrypt(recipientInfo));
            Assert.ThrowsAny<CryptographicException>(() => ecms.Decrypt(extraStore));
            Assert.ThrowsAny<CryptographicException>(() => ecms.Decrypt(recipientInfo, extraStore));
        }

        [Fact]
        [OuterLoop(/* Leaks key on disk if interrupted */)]
        public static void EnvelopedCmsDecryptWithoutMatchingCertSki()
        {
            // You don't have the private key? No message for you.

            // This is the private key that "we don't have." We want to force it to load anyway, though, to trigger
            // the "fail the test due to bad machine config" exception if someone left this cert in the MY store check.
            using (X509Certificate2 ignore = Certificates.RSAKeyTransfer1.TryGetCertificateWithPrivateKey())
            { }

            byte[] encodedMessage =
                ("3081f206092a864886f70d010703a081e43081e10201023181ae3081ab0201028014f2008aa9fa3742e8370cb1674ce1d158"
                + "2921dcc3300d06092a864886f70d01010105000481804336e978bc72ba2f5264cd854867fac438f36f2b3df6004528f2df83"
                + "4fb2113d6f7c07667e7296b029756222d6ced396a8fffed32be838eec7f2e54b9467fa80f85d097f7d1f0fbde57e07ab3d46"
                + "a60b31f37ef9844dcab2a8eef4fec5579fac5ec1e7ee82409898e17d30c3ac1a407fca15d23c9df2904a707294d78d4300ba"
                + "302b06092a864886f70d010701301406082a864886f70d03070408355c596e3e8540608008f1f811e862e51bbd").HexToByteArray();

            EnvelopedCms ecms = new EnvelopedCms();
            ecms.Decode(encodedMessage);
            RecipientInfo recipientInfo = ecms.RecipientInfos[0];
            X509Certificate2Collection extraStore = new X509Certificate2Collection();
            Assert.ThrowsAny<CryptographicException>(() => ecms.Decrypt(recipientInfo));
            Assert.ThrowsAny<CryptographicException>(() => ecms.Decrypt(extraStore));
            Assert.ThrowsAny<CryptographicException>(() => ecms.Decrypt(recipientInfo, extraStore));
        }

        [Fact]
        public static void AlgorithmIdentifierNullaryCtor()
        {
            AlgorithmIdentifier a = new AlgorithmIdentifier();
            Assert.Equal(Oids.TripleDesCbc, a.Oid.Value);
            Assert.Equal(0, a.KeyLength);
        }

        [Fact]
        public static void CmsRecipient1AryCtor()
        {
            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate())
            {
                CmsRecipient r = new CmsRecipient(cert);
                Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, r.RecipientIdentifierType);
                Assert.Same(cert, r.Certificate);
            }
        }

        [Fact]
        public static void CmsRecipientPassUnknown()
        {
            using (X509Certificate2 cert = Certificates.RSAKeyTransfer1.GetCertificate())
            {
                CmsRecipient r = new CmsRecipient(SubjectIdentifierType.Unknown, cert);
                Assert.Equal(SubjectIdentifierType.IssuerAndSerialNumber, r.RecipientIdentifierType);
                Assert.Same(cert, r.Certificate);
            }
        }

        [Fact]
        public static void CmsRecipientPassNullCertificate()
        {
            object ignore;
            Assert.Throws<ArgumentNullException>(() => ignore = new CmsRecipient(null));
            Assert.Throws<ArgumentNullException>(() => ignore = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, null));
        }

        [Fact]
        public static void ContentInfoNullOid()
        {
            object ignore;
            Assert.Throws<ArgumentNullException>(() => ignore = new ContentInfo(null, new byte[3]));
        }

        [Fact]
        public static void ContentInfoNullContent()
        {
            object ignore;
            Assert.Throws<ArgumentNullException>(() => ignore = new ContentInfo(null));
            Assert.Throws<ArgumentNullException>(() => ignore = new ContentInfo(null, null));
        }

        [Fact]
        public static void ContentInfoGetContentTypeNull()
        {
            Assert.Throws<ArgumentNullException>(() => ContentInfo.GetContentType(null));
        }

        [Fact]
        public static void ContentInfoGetContentTypeUnknown()
        {
            byte[] encodedMessage =
                 ("301A06092A864886F70D010700A00D040B48656C6C6F202E4E455421").HexToByteArray();
            Assert.ThrowsAny<CryptographicException>(() => ContentInfo.GetContentType(encodedMessage));
        }

        [Fact]
        public static void CryptographicAttributeObjectOidCtor()
        {
            Oid oid = new Oid(Oids.DocumentDescription);
            CryptographicAttributeObject cao = new CryptographicAttributeObject(oid);
            Assert.Equal(oid.Value, cao.Oid.Value);
            Assert.Equal(0, cao.Values.Count);
        }

        [Fact]
        public static void CryptographicAttributeObjectPassNullValuesToCtor()
        {
            Oid oid = new Oid(Oids.DocumentDescription);
            // This is legal and equivalent to passing a zero-length AsnEncodedDataCollection.
            CryptographicAttributeObject cao = new CryptographicAttributeObject(oid, null);
            Assert.Equal(oid.Value, cao.Oid.Value);
            Assert.Equal(0, cao.Values.Count);
        }

        [Fact]
        public static void CryptographicAttributeObjectMismatch()
        {
            Oid oid = new Oid(Oids.DocumentDescription);
            Oid wrongOid = new Oid(Oids.DocumentName);

            AsnEncodedDataCollection col = new AsnEncodedDataCollection();
            col.Add(new AsnEncodedData(oid, new byte[3]));

            object ignore;
            Assert.Throws<InvalidOperationException>(() => ignore = new CryptographicAttributeObject(wrongOid, col));
        }

        [Fact]
        public static void EncryptEnvelopedOctetStringWithIncompleteContent()
        {
            byte[] content = "04040203".HexToByteArray();
            ContentInfo contentInfo = new ContentInfo(new Oid(Oids.Pkcs7Enveloped), content);

            using (X509Certificate2 certificate = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                string certSubjectName = certificate.Subject;
                AlgorithmIdentifier alg = new AlgorithmIdentifier(new Oid(Oids.Aes256));
                EnvelopedCms ecms = new EnvelopedCms(contentInfo, alg);
                CmsRecipient cmsRecipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
                Assert.ThrowsAny<CryptographicException>(() => ecms.Encrypt(cmsRecipient));
            }
        }

        [Fact]
        public static void EncryptEnvelopedOneByteArray()
        {
            byte[] content = "04".HexToByteArray();
            ContentInfo contentInfo = new ContentInfo(new Oid(Oids.Pkcs7Enveloped), content);

            using (X509Certificate2 certificate = Certificates.RSAKeyTransferCapi1.GetCertificate())
            {
                string certSubjectName = certificate.Subject;
                AlgorithmIdentifier alg = new AlgorithmIdentifier(new Oid(Oids.Aes256));
                EnvelopedCms ecms = new EnvelopedCms(contentInfo, alg);
                CmsRecipient cmsRecipient = new CmsRecipient(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
                Assert.ThrowsAny<CryptographicException>(() => ecms.Encrypt(cmsRecipient));
            }
        }
    }
}


text:
layout: default
---

{{ page.title }}

                    {% if page.subtitle %}

{{ page.subtitle }}

                    {% endif %}
                    Posted by {{ page.author }} on {{ page.date | date: "%B %-d, %Y" }}

				{{ content }}

                {% include comments.html %}

                    {% if page.previous.url %}

                        ← Previous Post

                    {% endif %}
                    {% if page.next.url %}

                        Next Post →

                    {% endif %}

redpajama_set_name: RedPajamaGithub


text:
mout changelog
==============

v1.1.0 (2017/10/04)
--------------------
 - update dependencies
 - optimize `function/bind`
 - optimize `lang/kindOf`

v0.12.0 (2016/03/03)
--------------------
 - add `array/indicesOf`
 - add `function/memoize`
 - add `array/reverse`
 - add `math/overflow`
 - fix `query/getQuery`
 - fix `object/deepMatches`
 - optimize `function/partial`
 - updates license

v0.11.0 (2014/11/17)
--------------------

 - add `array/take`;
 - remove unused variable from `date/totalDaysInMonth`;
 - fix case insensitive RegExp cloning on `lang/clone`;

v0.10.0 (2014/09/02)
--------------------

 - add `array/equals`;
 - add `array/groupBy`;
 - add `array/last`;
 - add `function/wrap`;
 - add `lang/GLOBAL`;
 - add `lang/isPrimitive`;
 - add `number/MAX_SAFE_INTEGER`;
 - add `object/omit`;
 - add `object/result`;
 - add `object/result`;
 - add `random/randString`;
 - change `lang/isEmpty` behavior to return `true` for any value that isn't
   a collection.
 - fix `array/findLastIndex` to stop at zero index;
 - improve `function/partial` to accept placeholders;
 - improve `math.norm` behavior for values outside the range and for cases
   where `val === min === max`;
 - improve `object/get` behavior to return properties from any value that is
   not `null` or `undefined`;
 - move `object/deepEquals` to `lang/deepEquals` (improving the behavior);

v0.9.1 (2014/04/08)
-------------------

 - fix `array/slice` behavior when start and end are higher than length.

v0.9.0 (2014/02/04)
-------------------

 - add `date/quarter`;
 - add `function/constant`;
 - add `random/randBool`;
 - add un-padded 12-hour (`%l`) to `date/strftime`;
 - fix `array/slice` on IE < 9 by using a custom implementation.
 - fix `object/forIn` iteration for IE < 9 constructor property;
 - improve `lang/inheritPrototype` by returning the `prototype`;
 - improve `string/removeNonWord` to cover more chars;
 - improve `string/repeat` performance;
 - improve `string/unescapeHtml` by accepting leading zeros for `&#39`;

v0.8.0 (2013/11/22)
-------------------

 - add `array/findLast`.
 - add `array/findLastIndex`.
 - add `array/slice` and use it internally.
 - add `array/sortBy`
 - add `function/awaitDelay`.
 - add `function/identity`
 - add `number/isNaN`.
 - add `number/nth`.
 - add `number/ordinal`.
 - allows nested replacement patterns in `string/interpolate`.
 - change `function/makeIterator_` behavior (uses `identity` by default).
 - simplify `string/escapeRegExp`.
 - support custom equality on `array/compare`.

v0.7.1 (2013/09/18)
-------------------

 - fix `null` value handling in object/get.

v0.7.0 (2013/09/05)
-------------------

 - add bower ignores.
 - add german translation for date localization.
 - alias `function` package as `fn` since "function" is a reserved keyword.
 - allow second argument on `array/pick`.
 - improve `string/makePath` to not remove "//" after protocol.
 - make sure methods inside `number` package works with mixed types.
 - support arrays on `queryString/encode`.
 - support multiple values for same property on `queryString/decode`.
 - add `cancel()` method to `throttled/debounced` functions.
 - add `function/times`.
 - add `lang/toNumber`.
 - add `string/insert`.
 - add `super_` to constructor on `lang/inheritPrototype`.

v0.6.0 (2013/05/22)
-------------------

 - add optional delimeter to `string/unCamelCase`
 - allow custom char on `number/pad`
 - allow underscore characters in `string/removeNonWord`
 - accept `level` on `array/flatten` instead of a flag
 - convert underscores to camelCase in `string/camelCase`
 - remove `create()` from number/currencyFormat
 - add `date/dayOfTheYear`
 - add `date/diff`
 - add `date/isSame`
 - add `date/startOf`
 - add `date/strftime`
 - add `date/timezoneAbbr`
 - add `date/timezoneOffset`
 - add `date/totalDaysInYear`
 - add `date/weekOfTheYear`
 - add `function/timeout`
 - add `object/bindAll`
 - add `object/functions`
 - add `time/convert`

v0.5.0 (2013/04/04)
-------------------

 - add `array/collect`
 - add `callback` parameter to `object/equals` and `object/deepEquals` to allow
   custom compare operations.
 - normalize behavior in `array/*` methods to treat `null` values as empty
   arrays when reading from array
 - add `date/parseIso`
 - add `date/isLeapYear`
 - add `date/totalDaysInMonth`
 - add `object/deepMatches`
 - change `function/makeIterator_` to use `deepMatches` (affects nearly all
   iteration methods)
 - add `thisObj` parameter to `array/min` and `array/max`

v0.4.0 (2013/02/26)
-------------------

 - add `object/equals`
 - add `object/deepEquals`
 - add `object/matches`.
 - add `lang/is` and `lang/isnt`.
 - add `lang/isInteger`.
 - add `array/findIndex`.
 - add shorthand syntax to `array/*`, `object/*` and `collection/*` methods.
 - improve `number/sign` behavior when value is NaN or +0 or -0.
 - improve `lang/isNaN` to actually check if value *is not a number* without
   coercing value; so `[]`, `""`, `null` and `"12"` are considered NaN (#39).
 - improve `string/contains` to match ES6 behavior (add fromIndex argument).

v0.3.0 (2013/02/01)
-------------------

 - add `lang/clone`.
 - add `lang/toString`.
 - add `string/replace`.
 - add `string/WHITE_SPACES`
 - rename `function/curry` to `function/partial`.
 - allow custom chars in `string/trim`, `ltrim`, and `rtrim`.
 - convert values to strings in the `string/*` functions.

v0.2.0 (2013/01/13)
-------------------

 - fix bug in `math/ceil` for negative radixes.
 - change `object/deepFillIn` and `object/deepMixIn` to recurse only if both
   existing and new values are plain objects. Will not recurse into arrays
   or objects not created by the Object constructor.
 - add `lang/isPlainObject` to check if a file is a valid object and is created
   by the Object constructor
 - change `lang/clone` behavior when dealing with custom types (avoid cloning
   it by default) and add second argument to allow custom behavior if needed.
 - rename `lang/clone` to `lang/deepClone`.
 - add VERSION property to index.js
 - simplify `math/floor`, `math/round`, `math/ceil` and `math/countSteps`.

v0.1.0 (2013/01/09)
-------------------

- Rename project from "amd-utils" to "mout"


text:
package edu.mayo.phenoportal.shared;

import com.google.gwt.user.client.rpc.IsSerializable;

public class UserRoleRequest implements IsSerializable {

    private String id;
    private String userName;
    private String requestDate;
    private String responseDate;
    private boolean requestGranted;

    /**
     * @return the id
     */
    public String getId() {
        return id;
    }

    /**
     * @param id
     *            the id to set
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * @return the userName
     */
    public String getUserName() {
        return userName;
    }

    /**
     * @param userName
     *            the userName to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * @return the requestDate
     */
    public String getRequestDate() {
        return requestDate;
    }

    /**
     * @param requestDate
     *            the requestDate to set
     */
    public void setRequestDate(String requestDate) {
        this.requestDate = requestDate;
    }

    /**
     * @return the responseDate
     */
    public String getResponseDate() {
        return responseDate;
    }

    /**
     * @param responseDate
     *            the responseDate to set
     */
    public void setResponseDate(String responseDate) {
        this.responseDate = responseDate;
    }

    /**
     * @return the requestGranted
     */
    public boolean isRequestGranted() {
        return requestGranted;
    }

    /**
     * @param requestGranted
     *            the requestGranted to set
     */
    public void setRequestGranted(boolean requestGranted) {
        this.requestGranted = requestGranted;
    }

}


text:
<?xml version="1.0" encoding="UTF-8"?>
<servico versao="2" xmlns="http://servicos.gov.br/cartas-servico/v2/schema/servico" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://servicos.gov.br/cartas-servico/v2/schema/servico ../servico.xsd">
 <nome>
  Emissão da certidão de antecedentes criminais
 </nome>
 <nomes-populares>
 </nomes-populares>
 <descricao>Emissão do documento com validade de 90 (noventa) dias que informa a existência ou não de registros criminais nos sistemas informatizados.

* [Endereços das unidades do Departamento de Polícia Federal.](http://www.dpf.gov.br/institucional/pf-pelo-brasil)
* [Formulário de Requerimento de Antecedentes Criminais](http://www.dpf.gov.br/servicos/antecedentes-criminais/formulario-de-requerimento)
 </descricao>
 <palavras-chave>
 </palavras-chave>
 <areas-de-interesse>
  <area-de-interesse>
   <id>
    protecao-social
   </id>
   <area>Proteção social</area>
  </area-de-interesse>
 </areas-de-interesse>
 <segmentos-da-sociedade>
  <segmento-da-sociedade>
   <id>
    cidadaos
   </id>
   <nome>
    Cidadãos
   </nome>
  </segmento-da-sociedade>
 </segmentos-da-sociedade>
 <eventos-da-linha-da-vida>
  <evento-da-linha-da-vida>
   <id>
    documentos-e-certidoes
   </id>
   <nome>
    Documentos e certidões
   </nome>
  </evento-da-linha-da-vida>
 </eventos-da-linha-da-vida>
 <legislacao-relacionada></legislacao-relacionada>
 <solicitantes></solicitantes>
 <etapas>
  <etapa>
   <titulo>
   </titulo>
   <descricao>
   </descricao>
   <documentos></documentos>
   <custos excecoes="false">
    <custo>
     <descricao>
     </descricao>
     <valor>
     </valor>
    </custo>
   </custos>
   <canais-de-prestacao>
    <canal-de-prestacao tipo="Web" preferencial="true">
     <titulo>
     </titulo>
     <referencia>
      http://www.dpf.gov.br/servicos/antecedentes-criminais/
     </referencia>
    </canal-de-prestacao>
    <canal-de-prestacao tipo="Agendamento" preferencial="false">
     <titulo>
     </titulo>
     <referencia>
     </referencia>
    </canal-de-prestacao>
    <canal-de-prestacao tipo="Presencial" preferencial="false">
     <titulo>
     </titulo>
     <referencia>
     </referencia>
    </canal-de-prestacao>
   </canais-de-prestacao>
  </etapa>
 </etapas>
 <orgao>
  <id>
   ministerio-da-justica-mj
  </id>
  <nome>
   Ministério da Justiça (MJ)
  </nome>
 </orgao>
 <situacao>
 </situacao>
</servico>


text:
require 'helper'

class Nanoc::Filters::RelativizePathsTest < Nanoc::TestCase
  def test_filter_html_with_double_quotes
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %(foo)
    expected_content = %(foo)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_with_single_quotes
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %(foo)
    expected_content = %(foo)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_without_quotes
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %(foo)
    expected_content = %(foo)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_with_boilerplate
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content = <<EOS
<!DOCTYPE html>

    <title>Hello</title>

    foo

EOS
    expected0 = %r{foo}
    expected1 = %r{\A\s*<!DOCTYPE html\s*>\s*\s*(.|\s)*<title>Hello</title>\s*\s*\s*foo\s*\s*\s*\Z}m

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_match(expected0, actual_content)
    assert_match(expected1, actual_content)
  end

  def test_filter_html_multiple
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %(foo bar)
    expected_content = %(foo bar)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_nested
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %()
    expected_content = %()

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_outside_tag
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %(stuff href="/foo" more stuff)
    expected_content = %(stuff href="/foo" more stuff)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_root
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    # Set content
    raw_content      = %(foo)
    expected_content = %(foo)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_network_path
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    # Set content
    raw_content      = %(example.com)
    expected_content = %(example.com)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_with_anchor
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    # Set content
    raw_content      = %(Max Payne)
    expected_content = %(Max Payne)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_with_url
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    # Set content
    raw_content      = %(Example)
    expected_content = %(Example)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_with_relative_path
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    # Set content
    raw_content      = %(Example)
    expected_content = %(Example)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_html_object_with_relative_path
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    raw_content    = %(<object data="/example"><param name="movie" content="/example"></object>)
    actual_content = filter.setup_and_run(raw_content, type: :html)

    assert_match(/<object data="..\/..\/example">/, actual_content)
    assert_match(/<param (name="movie" )?content="..\/..\/example"/, actual_content)
  end

  def test_filter_form
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %(<form action="/example"></form>)
    expected_content = %(<form action="../../../example"></form>)

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :html)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_implicit
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Test
    assert_raises(RuntimeError) do
      filter.setup_and_run('moo')
    end
  end

  def test_filter_css_with_double_quotes
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %[background: url("/foo/bar/background.png");]
    expected_content = %[background: url("../background.png");]

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :css)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_css_with_single_quotes
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %[background: url('/foo/bar/background.png');]
    expected_content = %[background: url('../background.png');]

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :css)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_css_without_quotes
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %[background: url(/foo/bar/background.png);]
    expected_content = %[background: url(../background.png);]

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :css)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_css_multiple
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/foo/bar/baz/']
    end

    # Set content
    raw_content      = %[background: url(/foo/bar/a.png) url(/foo/bar/b.png);]
    expected_content = %[background: url(../a.png) url(../b.png);]

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :css)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_css_root
    # It is probably a bit weird to have "url(/)" in CSS, but I've made a
    # test case for this situation anyway. Can't hurt…

    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    # Set content
    raw_content      = %[background: url(/);]
    expected_content = %[background: url(../../);]

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :css)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_css_network_path
    # Create filter with mock item
    filter = Nanoc::Filters::RelativizePaths.new

    # Mock item
    filter.instance_eval do
      @item_rep = Nanoc::Int::ItemRep.new(
        Nanoc::Int::Item.new(
          'content',
          {},
          '/foo/bar/baz/',
        ),
        :blah,
      )
      @item_rep.paths[:last] = ['/woof/meow/']
    end

    # Set content
    raw_content      = %[background: url(//example.com);]
    expected_content = %[background: url(//example.com);]

    # Test
    actual_content = filter.setup_and_run(raw_content, type: :css)
    assert_equal(expected_content, actual_content)
  end

  def test_filter_xml
    if_have 'nokogiri' do
      # Create filter with mock item
      filter = Nanoc::Filters::RelativizePaths.new

      # Mock item
      filter.instance_eval do
        @item_rep = Nanoc::Int::ItemRep.new(
          Nanoc::Int::Item.new(
            'content',
            {},
            '/foo/bar/baz/',
          ),
          :blah,
        )
        @item_rep.paths[:last] = ['/foo/bar/baz/']
      end

      # Set content
      expected = /<bar boo="\.\.\/\.\.">baz<\/bar>/
      raw_content = <<-XML
<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar boo="/foo">baz</bar>
</foo>
XML

      actual_content = filter.setup_and_run(raw_content, type: :xml, select: ['*/@boo'])

      assert_match(expected, actual_content)
    end
  end

  def test_filter_fragment_xml
    if_have 'nokogiri' do
      # Create filter with mock item
      filter = Nanoc::Filters::RelativizePaths.new

      # Mock item
      filter.instance_eval do
        @item_rep = Nanoc::Int::ItemRep.new(
          Nanoc::Int::Item.new(
            'content',
            {},
            '/foo/bar/baz/',
          ),
          :blah,
        )
        @item_rep.paths[:last] = ['/foo/bar/baz/']
      end

      # Set content
      raw_content = <<-XML
<foo>
  <bar><far href="/foo">baz</far></bar>
</foo>
XML

      actual_content = filter.setup_and_run(raw_content, type: :xml, select: ['far/@href'])

      assert_match(/<foo>/, actual_content)
      assert_match(/<bar><far href="..\/..">baz<\/far><\/bar>/, actual_content)
    end
  end

  def test_filter_xml_with_namespaces
    if_have 'nokogiri' do
      # Create filter with mock item
      filter = Nanoc::Filters::RelativizePaths.new

      # Mock item
      filter.instance_eval do
        @item_rep = Nanoc::Int::ItemRep.new(
          Nanoc::Int::Item.new(
            'content',
            {},
            '/foo/bar/baz/',
          ),
          :blah,
        )
        @item_rep.paths[:last] = ['/foo/bar/baz/']
      end

      # Set content
      raw_content = <<-XML
<foo xmlns="http://example.org">
  <bar>baz</bar>
</foo>
XML

      options = {
        type: :xml,
        namespaces: { ex: 'http://example.org' },
        select: ['ex:a/@href'],
      }
      actual_content = filter.setup_and_run(raw_content, options)

      assert_match(/<foo xmlns="http:\/\/example.org">/,    actual_content)
      assert_match(/<bar>baz<\/a><\/bar>/, actual_content)
    end
  end

  def test_filter_xhtml
    if_have 'nokogiri' do
      # Create filter with mock item
      filter = Nanoc::Filters::RelativizePaths.new

      # Mock item
      filter.instance_eval do
        @item_rep = Nanoc::Int::ItemRep.new(
          Nanoc::Int::Item.new(
            'content',
            {},
            '/foo/bar/baz/',
          ),
          :blah,
        )
        @item_rep.paths[:last] = ['/foo/bar/baz/']
      end

      # Set content
      raw_content = <<-XML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

    <link rel="stylesheet" href="/css"/>

    bar

XML

      actual_content = filter.setup_and_run(raw_content, type: :xhtml)

      assert_match(/<link[^>]*href="..\/..\/..\/css"[^>]*\/>/, actual_content)
      assert_match(/
<![endif]-->

)

      actual_content = filter.setup_and_run(raw_content.freeze, type: :xhtml)

      assert_match(/<link (rel="stylesheet" )?href="..\/..\/foo.css" /,      actual_content)
      assert_match(/
<![endif]-->

)

      # Test
      actual_content = filter.setup_and_run(raw_content.freeze, type: :html)
      assert actual_content.include? %(


text:
package org.caleydo.view.tourguide.entourage.model;

import java.beans.PropertyChangeListener;
import java.util.BitSet;

import org.caleydo.core.util.color.Color;
import org.caleydo.core.view.opengl.layout2.GLElement;
import org.caleydo.core.view.opengl.layout2.GLGraphics;
import org.caleydo.core.view.opengl.layout2.IGLElementContext;
import org.caleydo.core.view.opengl.layout2.basic.EButtonIcon;
import org.caleydo.core.view.opengl.layout2.renderer.IGLRenderer;
import org.caleydo.core.view.opengl.picking.IPickingListener;
import org.caleydo.core.view.opengl.picking.Pick;
import org.caleydo.core.view.opengl.picking.PickingMode;
import org.caleydo.vis.lineup.model.ARankColumnModel;
import org.caleydo.vis.lineup.model.IRow;
import org.caleydo.vis.lineup.ui.GLPropertyChangeListeners;
import org.caleydo.vis.lineup.ui.detail.ValueElement;

/**
 * a special column model, showing a checkbox for the rows
 *
 * @author Samuel Gratzl
 *
 */
public class CheckColumnModel extends ARankColumnModel implements IGLRenderer {
	public static final String PROP_CHECKED = "checked";
	private final BitSet checked = new BitSet();

	public CheckColumnModel() {
		super(Color.GRAY, new Color(.95f, .95f, .95f));
		setWidth(20);
		setHeaderRenderer(this);
	}

	/**
	 * @param copy
	 */
	public CheckColumnModel(CheckColumnModel copy) {
		super(copy);
	}

	@Override
	public ARankColumnModel clone() {
		return new CheckColumnModel(this);
	}

	@Override
	public String getValue(IRow row) {
		return is(row) ? "Checked" : "Unchecked";
	}

	public boolean is(IRow row) {
		return checked.get(row.getIndex());
	}

	public void set(boolean value) {
		if (value)
			this.checked.set(0, getTable().getDataSize());
		else
			this.checked.clear();
		propertySupport.firePropertyChange(PROP_CHECKED, !value, value);
	}

	public void set(IRow row, boolean value) {
		boolean old = is(row);
		if (old == value)
			return;
		checked.set(row.getIndex(), value);
		propertySupport.fireIndexedPropertyChange(PROP_CHECKED, row.getIndex(), old, value);
	}

	@Override
	public GLElement createSummary(boolean interactive) {
		return new Summary();
	}

	@Override
	public ValueElement createValue() {
		return new Value();
	}

	/**
	 * @return the checked, see {@link #checked}
	 */
	public BitSet getChecked() {
		return checked;
	}

	private class Summary extends GLElement {

	}

	@Override
	public String toString() {
		return "Selection Model";
	}

	@Override
	public void render(GLGraphics g, float w, float h, GLElement parent) {
		if (w > 40)
			g.drawText("Active", 0, (h - 12) * 0.5f, w, 12);
	}

	private class Value extends ValueElement implements IPickingListener {
		private int pickingId = -1;
		private final PropertyChangeListener repaintListner = GLPropertyChangeListeners.repaintOnEvent(this);

		/**
		 *
		 */
		public Value() {
			setVisibility(EVisibility.VISIBLE);
		}

		@Override
		protected void init(IGLElementContext context) {
			pickingId = context.registerPickingListener(this);
			super.init(context);
			addPropertyChangeListener(PROP_CHECKED, repaintListner);
		}

		@Override
		protected void takeDown() {
			context.unregisterPickingListener(pickingId);
			removePropertyChangeListener(PROP_CHECKED, repaintListner);
			super.takeDown();
		}

		@Override
		public void pick(Pick pick) {
			if (pick.getPickingMode() == PickingMode.CLICKED) {
				set(getRow(), !is(getRow()));
				repaint();
			}
		}

		@Override
		protected void renderImpl(GLGraphics g, float w, float h, IRow row) {
			String icon = EButtonIcon.CHECKBOX.get(is(row));
			float hi = Math.min(h - 2, 16);
			g.fillImage(icon, (w - hi) * 0.5f, (h - hi) * 0.5f, hi, hi);
			// super.renderImpl(g, w, h);
		}

		@Override
		protected boolean hasPickAbles() {
			return true;
		}

		@Override
		protected void renderPickImpl(GLGraphics g, float w, float h) {
			g.pushName(pickingId);
			g.incZ();
			float hi = Math.min(h - 2, 16);
			g.fillRect((w - hi) * 0.5f, (h - hi) * 0.5f, hi, hi);
			g.decZ();
			g.popName();

			super.renderPickImpl(g, w, h);
		}
	}
}


text:
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace DotNetCommons.Web;

public class ApiErrorCatchingMiddleware
{
    private Stream Message(string msg)
    {
        return new MemoryStream(Encoding.UTF8.GetBytes(msg));
    }

    public async Task Middleware(HttpContext context, Func<Task> next)
    {
        if (!context.Request.Path.StartsWithSegments("/api"))
        {
            await next();
            return;
        }

        try
        {
            await next();
        }
        catch (ApiException e)
        {
            context.Response.StatusCode = (int)e.HttpCode;
            context.Response.Body = Message(e.Message);
        }
        catch
        {
            context.Response.StatusCode = 500;
            context.Response.Body = Message("Server Internal Error");
        }
    }
}


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
Denkschr. Kaiserl. Akad. Wiss. Wien, Math. -Naturwiss. Kl. 56:75. 1889

#### Original name
null

### Remarks
null


text:
import random
from matplotlib import pyplot as plt

# Accuracy of simulation.
amount = 1000

def dice():
    return random.randint(1,6)

# Returns list of dice rolled.
def dice_roller(amount):
    roll = []
    for i in range(amount):
        roll.append(dice())
    return sorted(roll)

# Runs a single attack capped at 3 attacking infantry
# and 2 defending infantry. Returns losses on each side
# in a dictionary.
def single_attack(attacking_infantry, defending_infantry):
    if defending_infantry >= 2: defense_roll = dice_roller(2)
    if defending_infantry == 1: defense_roll = dice_roller(1)

    if attacking_infantry >= 3: attack_roll = dice_roller(3)
    if attacking_infantry == 2: attack_roll = dice_roller(2)
    if attacking_infantry == 1: attack_roll = dice_roller(1)

    if attacking_infantry == 0 or defending_infantry == 0:
        print "Error"
        return "Error"

    attack_losses = 0
    defense_losses = 0
    # compare highest
    if defense_roll[-1] >= attack_roll[-1]:
        attack_losses += 1
    else:
        defense_losses += 1
    # second highest if defense has enough
    if defending_infantry >= 2 and attacking_infantry >= 2:
        if defense_roll[-2] >= attack_roll[-2]:
            attack_losses += 1
        else:
            defense_losses += 1
    return {'Defense Losses': defense_losses, 'Attack Losses': attack_losses}

# Runs until infantry on one side is depleted.
# Returns True if attack wins.
def battle(total_attacking_infantry, total_defending_infantry):
    total_attacking_losses = 0
    total_defending_losses = 0

    while True:
        attack = single_attack(total_attacking_infantry, total_defending_infantry)

        total_attacking_infantry -= attack['Attack Losses']
        total_attacking_losses += attack['Attack Losses']
        if total_attacking_infantry == 0: break

        total_defending_infantry -= attack['Defense Losses']
        total_defending_losses += attack['Defense Losses']
        if total_defending_infantry == 0: break

    # stop battle if one side runs out
    if total_defending_infantry > total_attacking_infantry:
        battle_result = False # attack lost
    else:
        battle_result = True # attack won

    return {'Battle Result':battle_result,
            'Total Attack Losses': total_attacking_losses,
            'Total Defense Losses': total_defending_losses
            }

# Runs mutliple battles and collects data
def simulator(attack, defense, amount):
    attack_wins = 0
    defense_wins = 0
    attack_losses = []
    defense_losses = []
    for i in range(amount):
        result = battle(attack, defense)
        if result['Battle Result'] == True:
            attack_wins += 1
        else:
            defense_wins += 1
        attack_losses.append(result['Total Attack Losses'])
        defense_losses.append(result['Total Defense Losses'])

    attack_win_rate = attack_wins / amount
    defense_win_rate = defense_wins / amount
    average_attack_losses = sum(attack_losses) / amount
    average_defense_losses = sum(defense_losses) / amount

    return {'Attack Wins':attack_wins,
            'Defense Wins':defense_wins,
            'Attack Win Rate': attack_win_rate,
            'Defense Win Rate': defense_win_rate,
            'Average Attack Losses': average_attack_losses,
            'Average Defense Losses': average_defense_losses,
            'Attack Infantry Losses': attack_losses,
            'Defense Infantry Losses': defense_losses
            }

# Prints a dataset.
def printdata(data):
    s = """
    Simulator Run %r Times:

    Attack Wins: %r
    Attack Win Rate: %r
    Average Attack Losses: %r

    Defense Wins: %r
    Defense Win Rate: %r
    Average Defense Losses: %r
    """ % (amount, data['Attack Wins'],
            data['Attack Win Rate'], data['Average Attack Losses'],
            data['Defense Wins'], data['Defense Win Rate'],
            data['Average Defense Losses'])
    print(s)

# Graphs a data set.
def graphdata(data):
    plt.hist(data['Attack Infantry Losses'], label='Attacker', color='blue')
    plt.title('Frequency of Attack Infantry Lost')
    plt.ylabel('Frequency')
    plt.xlabel('Attack Infantry Lost')
    plt.show()

def printsim(attack, defense):
    global amount
    data = simulator(attack, defense, amount)
    printdata(data)

def graphsim(attack, defense):
    global amount
    data = simulator(attack, defense, amount)
    graphdata(data)

def graphprintsim(attack, defense):
    global amount
    data = simulator(attack, defense, amount)
    printdata(data)
    graphdata(data)


text:
package com.microsoft.azure.cognitiveservices.knowledge.qnamaker.models;

import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
 * Context associated with Qna.
 */
public class ContextDTO {
    /**
     * To mark if a prompt is relevant only with a previous question or not.
     * true - Do not include this QnA as search result for queries without
     * context
     * false - ignores context and includes this QnA in search result.
     */
    @JsonProperty(value = "isContextOnly")
    private Boolean isContextOnly;

    /**
     * List of prompts associated with the answer.
     */
    @JsonProperty(value = "prompts")
    private List<PromptDTO> prompts;

    /**
     * Get the isContextOnly value.
     *
     * @return the isContextOnly value
     */
    public Boolean isContextOnly() {
        return this.isContextOnly;
    }

    /**
     * Set the isContextOnly value.
     *
     * @param isContextOnly the isContextOnly value to set
     * @return the ContextDTO object itself.
     */
    public ContextDTO withIsContextOnly(Boolean isContextOnly) {
        this.isContextOnly = isContextOnly;
        return this;
    }

    /**
     * Get the prompts value.
     *
     * @return the prompts value
     */
    public List<PromptDTO> prompts() {
        return this.prompts;
    }

    /**
     * Set the prompts value.
     *
     * @param prompts the prompts value to set
     * @return the ContextDTO object itself.
     */
    public ContextDTO withPrompts(List<PromptDTO> prompts) {
        this.prompts = prompts;
        return this;
    }

}


text:
package de.samdev.absgdx.tests.unittests.collisionTests;

import static org.junit.Assert.assertEquals;

import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import com.badlogic.gdx.math.Vector2;

import de.samdev.absgdx.framework.entities.colliosiondetection.geometries.CollisionBox;
import de.samdev.absgdx.framework.entities.colliosiondetection.geometries.CollisionCircle;
import de.samdev.absgdx.tests.dummy.DummyGameLayer;
import de.samdev.absgdx.tests.dummy.DummyNoCollisionTileMap;
import de.samdev.absgdx.tests.dummy.DummyNoTileCollisionEntity;

@RunWith(Parameterized.class)
public class CollisionBoxCircleTest extends CollisionTest {

	@Parameters(name= "({1}|{2}) / {0}")
	public static Collection<Object[]> data() { return getParameters(); }

	public CollisionBoxCircleTest(int mapScale, int mapW, int mapH) {
		super(mapScale, mapW, mapH);
	}

    //#########################################################################

    @Test
    public void testBoxCircleCollisionMovement_1D_X() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e1.setPosition(10, 10);
    	e2.setPosition(40, 10);

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	for (int i = 0; i < 400; i++)
    		e1.movePosition(0.1f, 0);

    	assertEqualsExt(new Vector2(38, 10), e1.getPosition());

    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-1-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-1", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollisionMovement_1D_Y() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e1.setPosition(10, 10);
    	e2.setPosition(10, 40);

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	for (int i = 0; i < 400; i++)
    		e1.movePosition(0, 0.1f);

    	assertEqualsExt(new Vector2(10, 38), e1.getPosition());

    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-1-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-1", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollisionMovement_2D() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e1.setPosition(10, 8.5f);
    	e2.setPosition(40, 10);

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	for (int i = 0; i < 400; i++)
    		e1.movePosition(0.1f, 0);

    	assertEqualsExt(new Vector2(38.1339746f, 8.5f), e1.getPosition(), 0.0001f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-1-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-1", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_T() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10f, 12.5f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10f, 10.5f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_TR() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(12f, 12f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10.5f, 10.5f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_R() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(12.5f, 10f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10.5f, 10f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_BR() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(12f, 8f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10.5f, 9.5f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_B() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10f, 7.5f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10f, 9.5f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_BL() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(8f, 8f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(9.5f, 9.5f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_L() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(7.5f, 10f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(9.5f, 10f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_TL() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(8f, 12f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(9.5f, 10.5f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }

    @Test
    public void testBoxCircleCollision_C() {
    	DummyGameLayer l = new DummyGameLayer(this.mapWidth, this.mapHeight, new DummyNoCollisionTileMap(this.mapWidth, this.mapHeight), this.expMapScale);

    	DummyNoTileCollisionEntity e1 = new DummyNoTileCollisionEntity();
    	l.addEntity(e1);
    	e1.addCollisionGeo(0.5f, 0.5f, new CollisionBox(e1, 2f, 2f));

    	DummyNoTileCollisionEntity e2 = new DummyNoTileCollisionEntity();
    	l.addEntity(e2);
    	e2.addCollisionGeo(0.5f, 0.5f, new CollisionCircle(e2, 1f));

    	e2.setPosition(10f, 10f);
    	e1.setPosition(100f, 100f);

    	assertEquals(null, l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(null, l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-0-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-0-0-0", e2.dummyCtrSignSummary());

    	e2.setPosition(10f, 10f);
    	e1.setPosition(10f, 10f);

    	assertEquals(e1.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e2.listCollisionGeometries().next()));
    	assertEquals(e2.listCollisionGeometries().next(), l.collisionMap().getFirstCollider(e1.listCollisionGeometries().next()));

    	assertEquals("0-1-1-0-0-0", e1.dummyCtrSignSummary());
    	assertEquals("0-1-0-1-0-0", e2.dummyCtrSignSummary());
    }
}


text:
Difficulty: Hard

https://leetcode.com/problems/maximum-score-words-formed-by-letters/

Given a non-negative integer num, Return its encoding string.

The encoding is done by converting the integer to a string using a secret function that you should deduce from the following table:

![table](table.png)

**Example 1:**
```
Input: num = 23
Output: "1000"
```

**Example 2:**
```
Input: num = 107
Output: "101100"
```

**Constraints:**

* 0 <= num <= 10^9


text:
package se.fearless.fettle.builder;

import com.googlecode.gentyref.TypeToken;
import org.junit.Before;
import org.junit.Test;
import se.fearless.fettle.Action;

import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.core.IsCollectionContaining.hasItems;
import static org.junit.Assert.assertThat;
import static se.fearless.fettle.builder.Actions.actions;
import static se.mockachino.Mockachino.mock;

public class ActionsTest {

	private static final TypeToken<Action<String, String, Void>> ACTION_TYPE_TOKEN = new TypeToken<Action<String, String, Void>>() {
	};

	private Action<String, String, Void> action1;
	private Action<String, String, Void> action2;
	private Action<String, String, Void> action3;
	private Action<String, String, Void> action4;
	private Action<String, String, Void> action5;

	@Before
	public void setUp() throws Exception {
		action1 = mock(ACTION_TYPE_TOKEN);
		action2 = mock(ACTION_TYPE_TOKEN);
		action3 = mock(ACTION_TYPE_TOKEN);
		action4 = mock(ACTION_TYPE_TOKEN);
		action5 = mock(ACTION_TYPE_TOKEN);
	}

	@Test
	public void singleActionIsIncludedInList() throws Exception {
		assertThat(actions(action1), hasItem(action1));
	}

	@Test
	@SuppressWarnings("unchecked")
	public void twoActionsAreIncludedInList() throws Exception {
		assertThat(actions(action1, action2), hasItems(action1, action2));
	}

	@Test
	@SuppressWarnings("unchecked")
	public void threeActionsAreIncludedInList() throws Exception {
		assertThat(actions(action1, action2, action3), hasItems(action1, action2, action3));
	}

	@Test
	@SuppressWarnings("unchecked")
	public void fourActionsAreIncludedInList() throws Exception {
		assertThat(actions(action1, action2, action3, action4), hasItems(action1, action2, action3, action4));
	}

	@Test
	@SuppressWarnings("unchecked")
	public void fiveActionsAreIncludedInList() throws Exception {
		assertThat(actions(action1, action2, action3, action4, action5), hasItems(action1, action2, action3, action4, action5));
	}
}


text:
package gr.ntua.ece.cslab.panic.core.models;

/**
 * This package contains classes used to approximate the target function
 * representing the performance metric of the application which is profiled.
 *
 * @author Giannis Giannakopoulos
 */


text:
package com.intellij.ui.mac;

import com.apple.eawt.*;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.ui.UISettingsListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.BuildNumber;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.wm.impl.IdeFrameDecorator;
import com.intellij.openapi.wm.impl.IdeFrameImpl;
import com.intellij.ui.CustomProtocolHandler;
import com.intellij.ui.mac.foundation.Foundation;
import com.intellij.ui.mac.foundation.ID;
import com.intellij.ui.mac.foundation.MacUtil;
import com.intellij.util.EventDispatcher;
import com.intellij.util.Function;
import com.sun.jna.Callback;
import com.sun.jna.Pointer;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.lang.reflect.Method;
import java.util.EventListener;
import java.util.LinkedList;
import java.util.concurrent.atomic.AtomicInteger;

import static com.intellij.ui.mac.foundation.Foundation.invoke;

/**
 * User: spLeaner
 */
public class MacMainFrameDecorator extends IdeFrameDecorator implements UISettingsListener {
  private static final Logger LOG = Logger.getInstance("#com.intellij.ui.mac.MacMainFrameDecorator");

  private final FullscreenQueue<Runnable> myFullscreenQueue = new FullscreenQueue<>();

  private final EventDispatcher<FSListener> myDispatcher = EventDispatcher.create(FSListener.class);

  private interface FSListener extends FullScreenListener, EventListener {}
  private static class FSAdapter extends FullScreenAdapter implements FSListener {}

  private static class FullscreenQueue <T extends Runnable> {
    private boolean waitingForAppKit = false;
    private LinkedList<Runnable> queueModel = new LinkedList<>();

    synchronized void runOrEnqueue (final T runnable) {
      if (waitingForAppKit) {
        enqueue(runnable);
      }
      else {
        ApplicationManager.getApplication().invokeLater(runnable);
        waitingForAppKit = true;
      }
    }

    synchronized private void enqueue (final T runnable) {
      queueModel.add(runnable);
    }

    synchronized void runFromQueue () {
      if (!queueModel.isEmpty()) {
        queueModel.remove().run();
        waitingForAppKit = true;
      } else {
        waitingForAppKit = false;
      }
    }
  }

  // Fullscreen listener delivers event too late,
  // so we use method swizzling here
  private final Callback windowWillEnterFullScreenCallBack = new Callback() {
    public void callback(ID self,
                         ID nsNotification)
    {
      invoke(self, "oldWindowWillEnterFullScreen:", nsNotification);
      enterFullscreen();
    }
  };

  private void enterFullscreen() {
    myInFullScreen = true;
    myFrame.storeFullScreenStateIfNeeded(true);
    myFullscreenQueue.runFromQueue();
  }

  private final Callback windowWillExitFullScreenCallBack = new Callback() {
    public void callback(ID self,
                         ID nsNotification)
    {
      invoke(self, "oldWindowWillExitFullScreen:", nsNotification);
      exitFullscreen();
    }
  };

  private void exitFullscreen() {
    myInFullScreen = false;
    myFrame.storeFullScreenStateIfNeeded(false);

    JRootPane rootPane = myFrame.getRootPane();
    if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, null);
    myFullscreenQueue.runFromQueue();
  }

  public static final String FULL_SCREEN = "Idea.Is.In.FullScreen.Mode.Now";
  private static boolean HAS_FULLSCREEN_UTILITIES;

  private static Method requestToggleFullScreenMethod;

  static {
    try {
      Class.forName("com.apple.eawt.FullScreenUtilities");
      requestToggleFullScreenMethod = Application.class.getMethod("requestToggleFullScreen", Window.class);
      HAS_FULLSCREEN_UTILITIES = true;
    } catch (Exception e) {
      HAS_FULLSCREEN_UTILITIES = false;
    }
  }
  public static final boolean FULL_SCREEN_AVAILABLE = SystemInfo.isJavaVersionAtLeast("1.6.0_29") && HAS_FULLSCREEN_UTILITIES;

  private static boolean SHOWN = false;

  private static Callback SET_VISIBLE_CALLBACK = new Callback() {
    public void callback(ID caller, ID selector, ID value) {
      SHOWN = value.intValue() == 1;
      SwingUtilities.invokeLater(CURRENT_SETTER);
    }
  };

  private static Callback IS_VISIBLE = new Callback() {
    public boolean callback(ID caller) {
      return SHOWN;
    }
  };

  private static AtomicInteger UNIQUE_COUNTER = new AtomicInteger(0);

  public static final Runnable TOOLBAR_SETTER = () -> {
    final UISettings settings = UISettings.getInstance();
    settings.setShowMainToolbar(SHOWN);
    settings.fireUISettingsChanged();
  };

  public static final Runnable NAVBAR_SETTER = () -> {
    final UISettings settings = UISettings.getInstance();
    settings.setShowNavigationBar(SHOWN);
    settings.fireUISettingsChanged();
  };

  @SuppressWarnings("Convert2Lambda")
  public static final Function<Object, Boolean> NAVBAR_GETTER = new Function<Object, Boolean>() {
    @Override
    public Boolean fun(Object o) {
      return UISettings.getInstance().getShowNavigationBar();
    }
  };

  @SuppressWarnings("Convert2Lambda")
  public static final Function<Object, Boolean> TOOLBAR_GETTER = new Function<Object, Boolean>() {
    @Override
    public Boolean fun(Object o) {
      return UISettings.getInstance().getShowMainToolbar();
    }
  };

  private static Runnable CURRENT_SETTER = null;
  private static Function<Object, Boolean> CURRENT_GETTER = null;
  private static CustomProtocolHandler ourProtocolHandler = null;

  private boolean myInFullScreen;

  public MacMainFrameDecorator(@NotNull final IdeFrameImpl frame, final boolean navBar) {
    super(frame);

    if (CURRENT_SETTER == null) {
      CURRENT_SETTER = navBar ? NAVBAR_SETTER : TOOLBAR_SETTER;
      CURRENT_GETTER = navBar ? NAVBAR_GETTER : TOOLBAR_GETTER;
      SHOWN = CURRENT_GETTER.fun(null);
    }

    ApplicationManager.getApplication().getMessageBus().connect(this).subscribe(UISettingsListener.TOPIC, this);

    final ID pool = invoke("NSAutoreleasePool", "new");

    int v = UNIQUE_COUNTER.incrementAndGet();

    try {
      if (SystemInfo.isMacOSLion) {
        if (!FULL_SCREEN_AVAILABLE) return;

        FullScreenUtilities.setWindowCanFullScreen(frame, true);
        // Native fullscreen listener can be set only once
        FullScreenUtilities.addFullScreenListenerTo(frame, new FullScreenListener() {
          @Override
          public void windowEnteringFullScreen(AppEvent.FullScreenEvent event) {
            myDispatcher.getMulticaster().windowEnteringFullScreen(event);
          }

          @Override
          public void windowEnteredFullScreen(AppEvent.FullScreenEvent event) {
            myDispatcher.getMulticaster().windowEnteredFullScreen(event);
          }

          @Override
          public void windowExitingFullScreen(AppEvent.FullScreenEvent event) {
            myDispatcher.getMulticaster().windowExitingFullScreen(event);
          }

          @Override
          public void windowExitedFullScreen(AppEvent.FullScreenEvent event) {
            myDispatcher.getMulticaster().windowExitedFullScreen(event);
          }
        });
        myDispatcher.addListener(new FSAdapter() {
          @Override
          public void windowEnteredFullScreen(AppEvent.FullScreenEvent event) {
            // We can get the notification when the frame has been disposed
            JRootPane rootPane = frame.getRootPane();
            if (rootPane != null) rootPane.putClientProperty(FULL_SCREEN, Boolean.TRUE);
            enterFullscreen();
            myFrame.validate();
          }

          @Override
          public void windowExitedFullScreen(AppEvent.FullScreenEvent event) {
            // We can get the notification when the frame has been disposed
            if (myFrame == null/* || ORACLE_BUG_ID_8003173*/) return;
            exitFullscreen();
            myFrame.validate();
          }
        });
      }
      else {
        final ID window = MacUtil.findWindowForTitle(frame.getTitle());
        if (window == null) return;

        // toggle toolbar
        String className = "IdeaToolbar" + v;
        final ID ownToolbar = Foundation.allocateObjcClassPair(Foundation.getObjcClass("NSToolbar"), className);
        Foundation.registerObjcClassPair(ownToolbar);

        final ID toolbar = invoke(invoke(className, "alloc"), "initWithIdentifier:", Foundation.nsString(className));
        Foundation.cfRetain(toolbar);

        invoke(toolbar, "setVisible:", 0); // hide native toolbar by default

        Foundation.addMethod(ownToolbar, Foundation.createSelector("setVisible:"), SET_VISIBLE_CALLBACK, "v*");
        Foundation.addMethod(ownToolbar, Foundation.createSelector("isVisible"), IS_VISIBLE, "B*");

        Foundation.executeOnMainThread(true, true, () -> {
          invoke(window, "setToolbar:", toolbar);
          invoke(window, "setShowsToolbarButton:", 1);
        });
      }
    }
    finally {
      invoke(pool, "release");
    }

    // extract to static method for exclude this from OpenURIHandler() {} anonymous class
    createProtocolHandler();
  }

  private static void createProtocolHandler() {
    if (ourProtocolHandler == null) {
      // install uri handler
      final ID mainBundle = invoke("NSBundle", "mainBundle");
      final ID urlTypes = invoke(mainBundle, "objectForInfoDictionaryKey:", Foundation.nsString("CFBundleURLTypes"));
      final ApplicationInfoEx info = ApplicationInfoImpl.getShadowInstance();
      final BuildNumber build = info != null ? info.getBuild() : null;
      if (urlTypes.equals(ID.NIL) && build != null && !build.isSnapshot()) {
        LOG.warn("no url bundle present. \n" +
                 "To use platform protocol handler to open external links specify required protocols in the mac app layout section of the build file\n" +
                 "Example: args.urlSchemes = [\"your-protocol\"] will handle following links: your-protocol://open?file=file&line=line");
        return;
      }
      ourProtocolHandler = new CustomProtocolHandler();
      Application.getApplication().setOpenURIHandler(new OpenURIHandler() {
        @Override
        public void openURI(AppEvent.OpenURIEvent event) {
          ourProtocolHandler.openLink(event.getURI());
        }
      });
    }
  }

  private void replaceNativeFullscreenListenerCallback() {
    ID awtWindow = Foundation.getObjcClass("AWTWindow");

    Pointer windowWillEnterFullScreenMethod = Foundation.createSelector("windowWillEnterFullScreen:");
    ID originalWindowWillEnterFullScreen = Foundation.class_replaceMethod(awtWindow, windowWillEnterFullScreenMethod,
                                                                          windowWillEnterFullScreenCallBack, "v@::@");

    Foundation.addMethodByID(awtWindow, Foundation.createSelector("oldWindowWillEnterFullScreen:"),
                             originalWindowWillEnterFullScreen, "v@::@");

    Pointer  windowWillExitFullScreenMethod = Foundation.createSelector("windowWillExitFullScreen:");
    ID originalWindowWillExitFullScreen = Foundation.class_replaceMethod(awtWindow, windowWillExitFullScreenMethod,
                                                                         windowWillExitFullScreenCallBack, "v@::@");

    Foundation.addMethodByID(awtWindow, Foundation.createSelector("oldWindowWillExitFullScreen:"),
                             originalWindowWillExitFullScreen, "v@::@");
  }

  @Override
  public void uiSettingsChanged(final UISettings uiSettings) {
    if (CURRENT_GETTER != null) {
      SHOWN = CURRENT_GETTER.fun(null);
    }
  }

  @Override
  public boolean isInFullScreen() {
    return myInFullScreen;
  }

  @Override
  public ActionCallback toggleFullScreen(final boolean state) {
    if (!SystemInfo.isMacOSLion || myFrame == null || myInFullScreen == state) return ActionCallback.REJECTED;
    final ActionCallback callback = new ActionCallback();
    myDispatcher.addListener(new FSAdapter() {
      @Override
      public void windowExitedFullScreen(AppEvent.FullScreenEvent event) {
        callback.setDone();
        myDispatcher.removeListener(this);
      }

      @Override
      public void windowEnteredFullScreen(AppEvent.FullScreenEvent event) {
        callback.setDone();
        myDispatcher.removeListener(this);
      }
    });

    myFullscreenQueue.runOrEnqueue(() -> toggleFullScreenNow());
    return callback;
  }

  public void toggleFullScreenNow() {
    try {
      requestToggleFullScreenMethod.invoke(Application.getApplication(), myFrame);
    }
    catch (Exception e) {
      LOG.error(e);
    }
  }
}