text:
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Cors;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin.Security.OAuth;
using Microsoft.Owin.Security.OAuth.Messages;
using Umbraco.Core;
using Umbraco.Core.Security;

namespace Umbraco.RestApi.Security
{
    /// <summary>
    /// A simple OAuth server provider to verify back office users
    /// </summary>
    public class UmbracoAuthorizationServerProvider : OAuthAuthorizationServerProvider
    {
        private readonly UmbracoAuthorizationServerProviderOptions _options;

        public UmbracoAuthorizationServerProvider(UmbracoAuthorizationServerProviderOptions options = null)
        {
            if (options == null)
                options = new UmbracoAuthorizationServerProviderOptions();
            _options = options;
        }

        /// <summary>
        /// Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are
        /// present on the request. If the web application accepts Basic authentication credentials,
        /// context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web
        /// application accepts "client_id" and "client_secret" as form encoded POST parameters,
        /// context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body.
        /// If context.Validated is not called the request will not proceed further.
        /// </summary>
        /// <param name="context">The context of the event carries information in and results out.</param>
        /// <returns>Task to enable asynchronous execution</returns>
        public override Task ValidateClientAuthentication(OAuthValidateClientAuthenticationContext context)
        {
            //TODO: This would work but would it be better to just have two different endpoints setup - one for members, one for users.
            //      Each of those would then support the "password", "authorization_code" grant_type

            //check for a custom parameter in the request which will dictate how with authenticate
            var uid = context.Parameters.Where(f => f.Key == "umb_auth").Select(f => f.Value).SingleOrDefault();
            if (uid == null || uid.Length == 0)
            {
                uid = new[] { UmbracoAuthType.UserPassword.ToString() };
            }
            context.OwinContext.Set("umb:authtype", uid[0]);

            var tokenEndpointRequest = new TokenEndpointRequest(context.Parameters);
            if (tokenEndpointRequest.IsAuthorizationCodeGrantType)
            {
                if (!context.TryGetBasicCredentials(out var clientId, out _))
                {
                    context.TryGetFormCredentials(out clientId, out _);
                }

                if (context.ClientId == null)
                {
                    context.Rejected();
                    context.SetError("invalid_client", "Client credentials could not be retrieved through the Authorization header.");
                    return Task.FromResult(0);
                }

                context.Validated(clientId);
            }
            else
            {
                context.Validated();
            }

            return Task.FromResult(0);

            // Called to validate that the origin of the request is a registered "client_id", and that the correct credentials for that client are
            // present on the request. If the web application accepts Basic authentication credentials,
            // context.TryGetBasicCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request header. If the web
            // application accepts "client_id" and "client_secret" as form encoded POST parameters,
            // context.TryGetFormCredentials(out clientId, out clientSecret) may be called to acquire those values if present in the request body.
            // If context.Validated is not called the request will not proceed further.

            //** Currently we just accept everything globally
            //context.Validated();
            //return Task.FromResult(0);

            // Example for checking registered clients:

            //** Validate that the data is in the request
            //string clientId;
            //string clientSecret;
            //if (context.TryGetFormCredentials(out clientId, out clientSecret) == false)
            //{
            //    context.SetError("invalid_client", "Form credentials could not be retrieved.");
            //    context.Rejected();
            //    return Task.FromResult(0);
            //}

            //var userManager = context.OwinContext.GetUserManager<BackOfficeUserManager>();

            //** Check if this client id is allowed/registered
            // - lookup in custom table

            //** Verify that the client id and client secret match
            //if (client != null && userManager.PasswordHasher.VerifyHashedPassword(client.ClientSecretHash, clientSecret) == PasswordVerificationResult.Success)
            //{
            //    // Client has been verified.
            //    context.Validated(clientId);
            //}
            //else
            //{
            //    // Client could not be validated.
            //    context.SetError("invalid_client", "Client credentials are invalid.");
            //    context.Rejected();
            //}
        }

        /// <summary>
        /// Called at the final stage of a successful Token endpoint request. An application may implement this call in order to do any final
        ///             modification of the claims being used to issue access or refresh tokens. This call may also be used in order to add additional
        ///             response parameters to the Token endpoint's json response body.
        /// </summary>
        /// <param name="context">The context of the event carries information in and results out.</param>
        /// <returns>
        /// Task to enable asynchronous execution
        /// </returns>
        /// <remarks>
        /// This validates the grant_type accepted and also processes CORS
        /// </remarks>
        public override Task ValidateTokenRequest(OAuthValidateTokenRequestContext context)
        {
            //TODO: Determine which grant types will will actually support - these will probably be the only ones
            if (!context.TokenRequest.IsAuthorizationCodeGrantType &&
                !context.TokenRequest.IsResourceOwnerPasswordCredentialsGrantType &&
                !context.TokenRequest.IsRefreshTokenGrantType)
            {
                context.Rejected();
                context.SetError("invalid_grant_type", "Only grant_type=authorization_code, grant_type=password or grant_type=refresh_token are accepted by this server.");
                return Task.FromResult(0);
            }

            ProcessCors(context);

            return base.ValidateTokenRequest(context);
        }

        /// <summary>
        /// Based on the information in the context will assign a ClaimsIdentity
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        /// <remarks>
        /// NOTE: This is "Resource Owner Password Credential Flow"
        /// </remarks>
        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
        {
            //TODO: Based on the context we need to create a ClaimsIdentity

            var authType = context.OwinContext.Get<string>("umb:authtype");
            if (!Enum<UmbracoAuthType>.TryParse(authType, true, out UmbracoAuthType parsed))
            {
                context.Rejected();
                context.SetError("invalid_umb_auth", "Unsupported Umbraco umb_auth");
                return;
            }

            switch (parsed)
            {
                case UmbracoAuthType.UserPassword:

                    var userManager = context.OwinContext.GetUserManager<BackOfficeUserManager>();
                    if (userManager == null)
                        throw new InvalidOperationException("No " + typeof(BackOfficeUserManager) + " found in the owin context");

                    var user = await userManager.FindAsync(context.UserName, context.Password);

                    if (user == null)
                    {
                        context.SetError("invalid_grant", "The user name or password is incorrect.");
                        return;
                    }

                    //TODO: This way Or the one below? same thing?
                    //var identity = user.GenerateUserIdentityAsync(userManager);
                    var identity = await userManager.ClaimsIdentityFactory.CreateAsync(userManager, user, context.Options.AuthenticationType);

                    context.Validated(identity);

                    break;
                case UmbracoAuthType.MemberPassword:
                    break;
                case UmbracoAuthType.UserAuthCode:
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

        }

        private void ProcessCors(OAuthValidateTokenRequestContext context)
        {
            var accessControlRequestMethodHeaders = context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestMethod);
            var originHeaders = context.Request.Headers.GetCommaSeparatedValues(CorsConstants.Origin);
            var accessControlRequestHeaders = context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestMethod);
            var corsRequest = new CorsRequestContext
            {
                Host = context.Request.Host.Value,
                HttpMethod = context.Request.Method,
                Origin = originHeaders?.FirstOrDefault(),
                RequestUri = context.Request.Uri,
                AccessControlRequestMethod = accessControlRequestMethodHeaders?.FirstOrDefault()
            };
            if (accessControlRequestHeaders != null)
            {
                foreach (var header in context.Request.Headers.GetCommaSeparatedValues(CorsConstants.AccessControlRequestMethod))
                {
                    corsRequest.AccessControlRequestHeaders.Add(header);
                }
            }

            var engine = new CorsEngine();

            if (corsRequest.IsPreflight)
            {
                try
                {
                    // Make sure Access-Control-Request-Method is valid.
                    var test = new HttpMethod(corsRequest.AccessControlRequestMethod);
                }
                catch (ArgumentException)
                {
                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    context.SetError("Access Control Request Method Cannot Be Null Or Empty");
                    //context.RequestCompleted();
                    return;
                }
                catch (FormatException)
                {
                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    context.SetError("Invalid Access Control Request Method");
                    //context.RequestCompleted();
                    return;
                }

                var result = engine.EvaluatePolicy(corsRequest, _options.CorsPolicy);

                if (!result.IsValid)
                {
                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    context.SetError(string.Join(" | ", result.ErrorMessages));
                    //context.RequestCompleted();
                    return;
                }

                WriteCorsHeaders(result, context);
            }
            else
            {
                var result = engine.EvaluatePolicy(corsRequest, _options.CorsPolicy);

                if (result.IsValid)
                {
                    WriteCorsHeaders(result, context);
                }
            }
        }

        private void WriteCorsHeaders(CorsResult result, OAuthValidateTokenRequestContext context)
        {
            var headers = result.ToResponseHeaders();

            if (headers != null)
            {
                foreach (var header in headers)
                {
                    context.Response.Headers.Append(header.Key, header.Value);
                }
            }
        }
    }
}


text:
package org.opencb.biodata.tools.variant.merge;

import htsjdk.variant.vcf.VCFConstants;
import org.apache.commons.lang3.StringUtils;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.opencb.biodata.models.feature.Genotype;
import org.opencb.biodata.models.variant.StudyEntry;
import org.opencb.biodata.models.variant.Variant;
import org.opencb.biodata.models.variant.VariantNormalizer;
import org.opencb.biodata.models.variant.VariantTestUtils;
import org.opencb.biodata.models.variant.avro.AlternateCoordinate;
import org.opencb.biodata.models.variant.avro.VariantType;
import org.opencb.biodata.models.variant.exceptions.NonStandardCompliantSampleField;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import static org.junit.Assert.*;

@SuppressWarnings("Duplicates")
public class VariantMergerTest {

    private VariantMerger variantMerger;
    private VariantMerger variantMergerCollapse;
    private Variant var;

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Before
    public void setUp() throws Exception {
        variantMerger = new VariantMerger();
        variantMergerCollapse = new VariantMerger(true);

        Variant tempate = VariantTestUtils.generateVariant("1",10,"A","T",VariantType.SNV,
                Arrays.asList("S01"),
                Arrays.asList(Genotype.HET_REF));
        var = variantMerger.createFromTemplate(tempate);
        variantMerger.merge(var, tempate);
    }

    @After
    public void tearDown() throws Exception {
    }

    public void speedTest() {
        int size = 10000;
        List<Variant> variants = new ArrayList<>();
        for (int i = 0; i < size; ++i) {
            Variant v = i%100 == 0 ?
                    VariantTestUtils.generateVariant("1:10:A:T", "S"+i, "0/1")
                    : VariantTestUtils.generateVariant("1:10:A:-", "S"+i, "0/0");
            v = i %301 == 0 ?
                    VariantTestUtils.generateVariant("1:10:A:G,CCC", "S"+i, "1/2"):
                    v;
            variants.add(v);
        }
        for (int i = 0; i < 100; i++) {
            Variant template = variantMerger.createFromTemplate(variants.get(0));
            long start = System.currentTimeMillis();
            Variant merged = variantMerger.merge(template, variants);
            long end = System.currentTimeMillis();
            System.out.println("end - start = " + (end - start));
            assertEquals(size, merged.getStudies().get(0).getSamplesName().size());
        }
    }

    @Test
    public void testCollapse_Deletion_SNP() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:ATT:", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:A:T", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:10:A:", "S03", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/0", se.getSampleData("S02", "GT"));
        assertEquals("0/0", se.getSampleData("S03", "GT"));
        assertEquals(0, se.getSecondaryAlternates().size());
    }

    @Test
    public void testCollapse_DEL_DEL() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:ATT:", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:ATT:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:10:A:", "S03", "0/1");
        Variant s04 = VariantTestUtils.generateVariant("1:9:AATT:", "S04", "0/1");
        Variant s05 = VariantTestUtils.generateVariant("1:10:ATTT:", "S05", "2/1");
        s05.getStudies().get(0).setSecondaryAlternates(Collections.singletonList(
                new AlternateCoordinate(s01.getChromosome(),s01.getStart(),s01.getEnd(), s01.getReference(), s01.getAlternate(), s01.getType())));
        Variant s06 = VariantTestUtils.generateVariant("1:10:A:", "S06", "1/2");
        s06.getStudies().get(0).setSecondaryAlternates(Collections.singletonList(
                new AlternateCoordinate(s04.getChromosome(),s04.getStart(),s04.getEnd(), s04.getReference(), s04.getAlternate(), s04.getType())));

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03, s04, s05, s06));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03", "S04", "S05", "S06"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/1", se.getSampleData("S02", "GT"));
        assertEquals("0/0", se.getSampleData("S03", "GT"));
        assertEquals("0/2", se.getSampleData("S04", "GT"));
        assertEquals("1/2", se.getSampleData("S05", "GT"));
        assertEquals("0/2", se.getSampleData("S06", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testCollapse_DEL_REF() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:ATT:-", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:ATT:-", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:10:A:-", "S03", "0/1");
        Variant s04 = VariantTestUtils.generateVariant("1:9:AATT:-", "S04", "0/1");
        Variant s05 = VariantTestUtils.generateVariant("1:3:A:-", "S05", "0/0");
        s05.setType(VariantType.NO_VARIATION);
        s05.setEnd(15);

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03, s04, s05));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03", "S04", "S05"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/1", se.getSampleData("S02", "GT"));
        assertEquals("0/0", se.getSampleData("S03", "GT"));
        assertEquals("0/2", se.getSampleData("S04", "GT"));
        assertEquals("0/0", se.getSampleData("S05", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testCollapse_SNP_REF() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:ATT:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:10:A:", "S03", "0/1");
        Variant s04 = VariantTestUtils.generateVariant("1:9:AATT:", "S04", "0/1");
        Variant s05 = VariantTestUtils.generateVariant("1:3:A:", "S05", "0/0");
        s05.setType(VariantType.NO_VARIATION);
        s05.setEnd(15);

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03, s04, s05));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03", "S04", "S05"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
        assertEquals("0/2", se.getSampleData("S04", "GT"));
        assertEquals("0/0", se.getSampleData("S05", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testCollapse_SNP_INS() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:ATT:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:11::T", "S03", "0/1");
        Variant s04 = VariantTestUtils.generateVariant("1:11::TTTT", "S04", "0/1");
        Variant s05 = VariantTestUtils.generateVariant("1:3:A:", "S05", "0/0");
        s05.setType(VariantType.NO_VARIATION);
        s05.setEnd(15);

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03, s04, s05));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03", "S04", "S05"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
        assertEquals("0/2", se.getSampleData("S04", "GT"));
        assertEquals("0/0", se.getSampleData("S05", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testCollapse_SNP_DEL() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:A:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:9:AATT:", "S03", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testCollapse_SNP_MNV() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:AGC:TCA", "S02", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("TCA", se.getSecondaryAlternates().get(0).getAlternate());
        assertEquals("AGC", se.getSecondaryAlternates().get(0).getReference());
    }

    @Test
    public void testCollapse_INS_REF() {
        Variant s01 = VariantTestUtils.generateVariant("1:11::T", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:ATT:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:10:A:", "S03", "0/1");
        Variant s04 = VariantTestUtils.generateVariant("1:9:AATT:", "S04", "0/1");
        Variant s05 = VariantTestUtils.generateVariant("1:3:A:", "S05", "0/0");
        s05.setType(VariantType.NO_VARIATION);
        s05.setEnd(15);

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03, s04, s05));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03", "S04", "S05"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
        assertEquals("0/2", se.getSampleData("S04", "GT"));
        assertEquals("0/0", se.getSampleData("S05", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testCollapse_DEL_DEL_larger() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:A:", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:AT:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:9:AATT:", "S03", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }
    @Test
    public void testCollapse_INS_DEL_larger() {
        Variant s01 = VariantTestUtils.generateVariant("1:10::A", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:9:AAT:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:9:A:T", "S03", "0/1");
        Variant s04 = VariantTestUtils.generateVariant("1:10::AA", "S04", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03, s04));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03", "S04"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
        assertEquals("0/2", se.getSampleData("S04", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testCollapse_MNV_DEL_larger() {
        Variant s01 = VariantTestUtils.generateVariant("1:9:AT:GC", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:9:AAT:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:9:A:T", "S03", "0/1");
        Variant s04 = VariantTestUtils.generateVariant("1:10::AA", "S04", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03, s04));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03", "S04"), se.getOrderedSamplesName());
        assertEquals(2, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/3", se.getSampleData("S03", "GT")); // NOT * for MNV
        assertEquals("0/2", se.getSampleData("S04", "GT"));
    }

    @Test
    public void testCollapse_MNV_DEL() {
        Variant s01 = VariantTestUtils.generateVariant("1:10:AT:TG", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:A:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:9:AATT:", "S03", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02", "S03"), se.getOrderedSamplesName());
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S02", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
    }

    @Test
    public void testCollapse_INS_DEL() {
        Variant s01 = VariantTestUtils.generateVariant("1:10::TT", "S01", "0/1");
        Variant s02 = VariantTestUtils.generateVariant("1:10:A:", "S02", "0/1");
        Variant s03 = VariantTestUtils.generateVariant("1:9:AATT:", "S03", "0/1");

        Variant var = variantMergerCollapse.merge(s01, Arrays.asList(s02, s03));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S03"), se.getOrderedSamplesName());
        assertEquals("0/1", se.getSampleData("S01", "GT"));
        assertEquals("0/2", se.getSampleData("S03", "GT"));
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("*", se.getSecondaryAlternates().get(0).getAlternate());
    }

    @Test
    public void testMerge_SecAltOverlapOnly() {
        Variant s02 = VariantTestUtils.generateVariant("1:9:A:T", "S02", "1/2");
        s02.getStudies().get(0).setSecondaryAlternates(Collections.singletonList(new AlternateCoordinate("1",9,11,"AAA","",VariantType.INDEL)));

        Variant merged = variantMerger.merge(var, Collections.singletonList(s02));
        assertEquals(2,merged.getStudies().get(0).getSamplesName().size());
    }

    @Test
    public void testMergeSame_3SNP() {
        variantMerger.merge(var, VariantTestUtils.generateVariant("1:10:A:T", "S02", "0/1"));
        assertEquals(Arrays.asList(lst("0/1"),lst("0/1")),
                onlyField(variantMerger.getStudy(var).getSamplesData(),0));

        String[] samples = new String[]{"S01","S02"};
        Map<String, Integer> collect = IntStream.range(0, 2).mapToObj(i -> i).collect(Collectors.toMap(i -> (String) samples[i], i-> i));
        assertEquals(collect,
                variantMerger.getStudy(var).getSamplesPosition());

        variantMerger.merge(var, VariantTestUtils.generateVariant("1:10:A:T", "S03", "0/0"));
        assertEquals(Arrays.asList(lst("0/1"),lst("0/1"),lst("0/0")),
                onlyField(variantMerger.getStudy(var).getSamplesData(),0));
    }

    @Test
    public void testMergeSame_2INDEL() {
        Variant var = variantMerger.merge(VariantTestUtils.generateVariant("1:10:A:", "S01", "0/0"), VariantTestUtils.generateVariant("1:10:A:", "S02", "0/1"));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);

        assertEquals(Arrays.asList("S01", "S02"), se.getOrderedSamplesName());
        assertEquals("0/0", se.getSampleData("S01", "GT"));
        assertEquals("0/1", se.getSampleData("S02", "GT"));
        assertEquals(0, se.getSecondaryAlternates().size());
    }

    private List<List<String>> onlyField(List<List<String>> samplesData, int i) {
        return samplesData.stream().map(e -> Arrays.asList(e.get(i))).collect(Collectors.toList());
    }

    @Test
    public void testMergeDifferentSimple() {
        variantMerger.merge(var, VariantTestUtils.generateVariant("1",10,"A","G",VariantType.SNV,
                Arrays.asList("S02"),
                Arrays.asList("0/0")));
        assertEquals(Arrays.asList(lst("0/1"),lst("0/0")),
                onlyField(variantMerger.getStudy(var).getSamplesData(),0));
    }

    @Test
    public void testExpectedSamplesDefaultValues() {
        variantMerger.merge(var, VariantTestUtils.generateVariant("1",10,"A","G",VariantType.SNV,
                Arrays.asList("S02"),
                Arrays.asList("0/0")));
        assertEquals(Arrays.asList(lst("0/1"),lst("0/0")),
                onlyField(var.getStudies().get(0).getSamplesData(),0));
        List<Variant> empty = new ArrayList<>();
        variantMerger.setExpectedSamples(Arrays.asList("S01", "S02", "SX"));
        variantMerger.merge(var, empty);
        assertEquals(Arrays.asList(lst("0/1"), lst("0/0"), lst(".")),
                onlyField(var.getStudies().get(0).getSamplesData(), 0));

        variantMerger.addExpectedSamples(lst("SY"));
        variantMerger.setDefaultValue(variantMerger.getGtKey(), "???");
        variantMerger.setDefaultValue(variantMerger.getFilterKey(), "xxx");
        variantMerger.merge(var, empty);
        assertEquals(Arrays.asList(lst("0/1"),lst("0/0"), lst("."), lst("???")),
                onlyField(variantMerger.getStudy(var).getSamplesData(),0));
        assertEquals(".", variantMerger.getStudy(var).getSampleData("SX", variantMerger.getFilterKey()));
        assertEquals("xxx", variantMerger.getStudy(var).getSampleData("SY", variantMerger.getFilterKey()));
        variantMerger.setExpectedSamples(Arrays.asList());
    }

    @Test
    public void testMergeDifferentComplex() {
        variantMerger.merge(var, VariantTestUtils.generateVariant("1", 10, "A", "G", VariantType.SNV,
                Arrays.asList("S02"),
                Arrays.asList("0/1")));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals(Collections.singletonList(new AlternateCoordinate("1", 10, 10, "A", "G", VariantType.SNV)), se.getSecondaryAlternates());
        assertEquals(Arrays.asList(lst("0/1"),lst("0/2")),
                onlyField(se.getSamplesData(), 0));
        assertEquals(Arrays.asList("S01", "S02"), se.getOrderedSamplesName());
    }

    @Test
    public void testEqualsVariantAltSecAlt() {
        Variant v = new Variant("1:1050:CTTTC:-");
        AlternateCoordinate a1 = new AlternateCoordinate(null, 1050, 1050, "C", "T", VariantType.SNV);
        AlternateCoordinate a2 = new AlternateCoordinate("1", 1054, 1054, "C", "T", VariantType.SNV);
        assertFalse(variantMerger.equals(a1, a2));
    }

    @Test
    public void testValidateEmptyFields() {
        thrown.expect(IllegalStateException.class);
        Variant v = new Variant("1:1050:CTTTC:-");
        AlternateCoordinate a1 = new AlternateCoordinate(null, 1050, null, "C", "T", VariantType.SNV);
        variantMerger.validateAlternate(a1);
    }

    @Test
    public void testMergeSecondaryAlternateToIdx() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:AT:T", "Sx", "1/2");
        AlternateCoordinate a1 = new AlternateCoordinate("1", 10, 10, "ATG", "G", VariantType.SNV);
        var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(a1);

        List<String> sampleList = new ArrayList<>();
        List<Variant> variantList = new ArrayList<>();
        List<AlternateCoordinate> secondaryAlternateList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            String sample = "S"+i;

            Variant v = VariantTestUtils.generateVariant("1:10:ATG"+ StringUtils.repeat("T",i)+":T", sample, "1/2");
            AlternateCoordinate a = new AlternateCoordinate("1", 10, 10, "ATG", "G"+StringUtils.repeat('G',i), VariantType.SNV);
            v.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(a);
            sampleList.add(sample);
            variantList.add(v);
            secondaryAlternateList.add(a);
        }

        Variant merged = variantMerger.merge(var1, variantList);
        StudyEntry studyEntry = merged.getStudies().get(0);

        for (int i = 0; i < 10; i++) {
            String gt = studyEntry.getSampleData(sampleList.get(i), "GT");
            Variant variant = variantList.get(i);
            AlternateCoordinate variantAlt = secondaryAlternateList.get(i);
            for (Genotype gto : Genotype.parse(gt)) {
                for (int gidx : gto.getAllelesIdx()) {
                    assertNotEquals(0, gidx);
                    assertNotEquals(1, gidx);
                    gidx -= 2;
                    AlternateCoordinate secAlt = studyEntry.getSecondaryAlternates().get(gidx);
                    assertTrue(VariantMerger.isSameVariant(variant, secAlt) || VariantMerger.isSameVariant(variantAlt, secAlt));
                }
            }
        }
    }

    @Test
    public void testMergeLotsOAlt() {
        Variant var = variantMerger.merge(VariantTestUtils.generateVariant("1:100:CTTTC:-", "S01", "0/1"), VariantTestUtils.generateVariant("1:104:C:T", "S02", "0/1"));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals(Collections.singletonList(new AlternateCoordinate("1", 104, 104, "C", "T", VariantType.SNV)), se.getSecondaryAlternates());
        assertEquals(Arrays.asList(lst("0/1"),lst("0/2")),
                onlyField(se.getSamplesData(), 0));
        assertEquals(Arrays.asList("S01", "S02"), se.getOrderedSamplesName());
        for (List<String> sampleData : se.getSamplesData()) {
            assertEquals(se.getFormat().size(), sampleData.size());
        }
    }

    @Test
    public void testMergeDifferentComplex2() {
        Variant var = variantMerger.merge(VariantTestUtils.generateVariant("1:10:A:G", "S02", "0/1"), VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/1"));
        StudyEntry se = var.getStudy(VariantTestUtils.STUDY_ID);
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals(Collections.singletonList(new AlternateCoordinate("1", 10, 10, "A", "T", VariantType.SNV)), se.getSecondaryAlternates());
        assertEquals(Arrays.asList(lst("0/1"),lst("0/2")),
                onlyField(se.getSamplesData(), 0));
        assertEquals(Arrays.asList("S02", "S01"), se.getOrderedSamplesName());
        for (List<String> sampleData : se.getSamplesData()) {
            assertEquals(se.getFormat().size(), sampleData.size());
        }
    }

    @Test
    public void testMergeIndelCase1() throws NonStandardCompliantSampleField {
        Variant v1 = new Variant("1:328:CTT:C");
        v1 = VariantTestUtils.generateVariant(v1, v1.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S1"), Collections.singletonList(Arrays.asList("1/2","PASS")), Collections.emptyMap());
        v1.getStudies().get(0).getSecondaryAlternates().add(new AlternateCoordinate(null,null,331,"CTT", "CTTTC", VariantType.INDEL));

        Variant v2 = new Variant("1:331:T:TCT");
        v2 = VariantTestUtils.generateVariant(v2, v2.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S1"), Collections.singletonList(Arrays.asList("0/1","PASS")), Collections.emptyMap());

        List<Variant> variants = new VariantNormalizer().normalize(Arrays.asList(v1, v2), false);
        variants.forEach(v -> System.out.println(v.toJson()));
        assertEquals(3, variants.size());
    }

    @Test
    public void testMergeIndelOverlapping() throws NonStandardCompliantSampleField {
        thrown.expect(IllegalStateException.class);
        Variant v1 = new Variant("1:10:TACACACACAC:TACACAC");
        v1 = VariantTestUtils.generateVariant(v1, v1.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S1"), Collections.singletonList(Arrays.asList("1/2","PASS")), Collections.emptyMap());
        v1.getStudies().get(0).getSecondaryAlternates().add(new AlternateCoordinate("1",10,21,"TACACACACAC", "T", VariantType.INDEL));

        Variant v2 = new Variant("1:11:A:.");
        v2 = VariantTestUtils.generateVariant(v2, v2.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S2"), Collections.singletonList(Arrays.asList("0/0","PASS")), Collections.emptyMap());

        System.out.println(v1.toJson());
        List<Variant> variants = new VariantNormalizer().normalize(Collections.singletonList(v1), false);
        for (Variant variant : variants) {
            List<AlternateCoordinate> alts = variant.getStudies().get(0).getSecondaryAlternates();
            for (AlternateCoordinate alt : alts) {
                alt.setChromosome(variant.getChromosome());
                if (alt.getStart() == null) {
                    alt.setStart(variant.getStart());
                }
            }
        }

        variants.stream().forEach(v -> System.out.println("v.toJson() = " + v.toJson()));

        // Fails down to normalization producing two variants with same GT (1/2 and 2/1)
        Variant mergeVar = variantMerger.merge(v2, variants);
        System.out.println("mergeVar = " + mergeVar.toJson());
    }

    @Test
    public void testMergeReference() {
        Variant v1 = new Variant("1:10:ATGTA:-");
        v1 = VariantTestUtils.generateVariant(v1, v1.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S1"), Collections.singletonList(Arrays.asList("0/1", "PASS")), Collections.emptyMap());

        Variant v2 = new Variant("1:10:A:.");
        v2 = VariantTestUtils.generateVariant(v2, v2.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S2"), Collections.singletonList(Arrays.asList("0/0", "PASS")), Collections.emptyMap());

        Variant v3 = new Variant("1:12:T:.");
        v3 = VariantTestUtils.generateVariant(v3, v3.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S2"), Collections.singletonList(Arrays.asList("./.", "XXX")), Collections.emptyMap());

        Variant mergeVar = variantMerger.merge(v1, v2);
        assertEquals(0, mergeVar.getStudies().get(0).getSecondaryAlternates().size());
        assertEquals("0/0", mergeVar.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_KEY));
        assertEquals("PASS", mergeVar.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_FILTER_KEY));
        Variant mergeVar2 = variantMerger.merge(mergeVar, v3);
        assertEquals("0/0", mergeVar2.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_KEY));
        assertEquals("PASS", mergeVar.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_FILTER_KEY));
    }

    @Test
    public void testMergeIndel() {
        Variant v1 = new Variant("1:10:ATGTA:-");
        v1 = VariantTestUtils.generateVariant(v1, v1.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S1"), Collections.singletonList(Arrays.asList("0/1","PASS")), Collections.emptyMap());

        Variant v2 = new Variant("1:10:A:T");
        v2 = VariantTestUtils.generateVariant(v2, v2.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S2"), Collections.singletonList(Arrays.asList("1/1","PASS")), Collections.emptyMap());

        Variant v3 = new Variant("1:12:T:A");
        v3 = VariantTestUtils.generateVariant(v3, v3.getType(),
                Arrays.asList(VCFConstants.GENOTYPE_KEY, VCFConstants.GENOTYPE_FILTER_KEY),
                Arrays.asList("S2"), Collections.singletonList(Arrays.asList("0/1","XXX")), Collections.emptyMap());

        Variant mergeVar = variantMerger.merge(v1, v2);
        assertEquals(1, mergeVar.getStudies().get(0).getSecondaryAlternates().size());
        assertEquals("2/2", mergeVar.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_KEY));
        assertEquals("PASS", mergeVar.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_FILTER_KEY));

        Variant mergeVar2 = variantMerger.merge(mergeVar, v3);
        assertEquals(2, mergeVar.getStudies().get(0).getSecondaryAlternates().size());
        assertEquals(new HashSet<>(Arrays.asList("2/2","0/3")), new HashSet<>(Arrays.asList(mergeVar2.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_KEY).split(","))));
        assertEquals("PASS,XXX", mergeVar.getStudies().get(0).getSampleData("S2", VCFConstants.GENOTYPE_FILTER_KEY));
    }

//    @Test(expected = IllegalStateException.class)
    public void testMergeIndelDuplicates() {
        Variant v1 = VariantTestUtils.generateVariant("1:10:ATGTA:-", "S1", "0/1");
        Variant v2 = VariantTestUtils.generateVariant("1:10:A:T", "S2", "0/1");
        Variant v3 = VariantTestUtils.generateVariant("1:10:A:T", "S2", "0/1");
        Variant mergeVar = variantMerger.merge(v1, v2);
        Variant mergeVar2 = variantMerger.merge(mergeVar, v3);
        assertEquals("0/1", mergeVar2.getStudies().get(0).getSampleData("S1", "GT"));
        assertEquals("0/2", mergeVar2.getStudies().get(0).getSampleData("S2", "GT"));
    }

    @Test()
    public void testMergeIndelOverlap() {
        Variant v1 = VariantTestUtils.generateVariant("1:10:ATGTA:-", "S1", "0/1");
        Variant v2 = VariantTestUtils.generateVariant("1:10:AT:-", "S2", "0/1");
        Variant v3 = VariantTestUtils.generateVariant("1:11:T:A", "S2", "0/1");
        Variant mergeVar = variantMerger.merge(v1, v2);
        Variant mergeVar2 = variantMerger.merge(mergeVar, v3);
    }

    @Test
    public void testMergeSame_2SNV() {
        checkSameNoSecondaries("1:10:A:T");
        checkSameNoSecondaries("1:10:AT:TA");
        checkMergeVariantsNoSecondaries(
                VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/0", "S02", "0/0"),
                VariantTestUtils.generateVariant("1:10:A:T", "S03", "0/1", "S04", "1/1", "S05", "1/1", "S06", "1/1"),
                "0/1", "1/1", "1/1", "1/1");
    }

    @Test
    public void testMergeSameWithSameAlternates_2SNV() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/0", "S02", "0/0");
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:T", "S03", "0/1", "S04", "1/1", "S05", "1/1", "S06", "1/1");
        AlternateCoordinate alternate = new AlternateCoordinate("1", 10, 10, "A", "G", VariantType.SNV);
        var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(alternate);
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(alternate);
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G"), "0/1", "1/1", "1/1", "1/1");
    }

    @Test
    public void testMergeSame_SNV_SNP() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:T", "S1", "0/0", "S2", "0/0");
        var1.setType(VariantType.SNP);
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:T", "S3", "0/1", "S4", "1/1");
        var2.setType(VariantType.SNV);

        checkMergeVariants(var1, var2, Collections.emptyList(), "0/1", "1/1");
    }

    @Test
    public void testMergeSameWithDifferentAlternates_2SNV() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/0", "S02", "0/0");
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:T", "S03", "0/1", "S04", "1/1", "S05", "1/1", "S06", "1/1");
        var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "G", VariantType.SNV));
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "0/1", "1/1", "1/1", "1/1");
    }

    @Test
    public void testMergeSameWithSameUnorderedAlternates_2SNV() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "1/2", "S02", "2/3");
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:T", "S03", "0/1", "S04", "1/1", "S05", "0/2", "S06", "0/3");
        var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "G", VariantType.SNV));
        var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "G", VariantType.SNV));
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "0/1", "1/1", "0/3", "0/2");
    }

    @Test
    public void testMergeSame_2DEL() {
        checkSameNoSecondaries("1:10:A:");
        checkSameNoSecondaries("1:10:AT:T");
    }

    @Test
    public void testMergeSame_2IN() {
        checkSameNoSecondaries("1:10::AA");
        checkSameNoSecondaries("1:10:A:AAA");
    }

    @Test
    public void testMergeOverlap_2DEL() {
        checkOverlapNoSecondaries("1:10:A:", "1:10:AT:");
    }

    @Test
    public void testMergeOverlap_2DEL_2() {
        checkOverlapNoSecondaries("1:11:T:", "1:10:AT:");
    }

    @Test
    public void testMergeOverlap_2DEL_3() {
        checkOverlapNoSecondaries("1:10:AT:", "1:11:T:");
    }

    @Test
    public void testMergeOverlap_2IN() {
        checkOverlapNoSecondaries("1:10::AT", "1:10::GGG");
    }

    @Test
    public void testMergeOverlap_IN_SNP() {
        checkOverlapNoSecondaries("1:10::AT", "1:9:A:G");
    }

    @Test
    public void testMergeOverlap_IN_SNP_SameSubject() {
        // see https://github.com/opencb/biodata/issues/100
        String sample = "S01";
        Variant var1 = VariantTestUtils.generateVariant("1:10::AT", sample, "0/1");
        Variant var2 = VariantTestUtils.generateVariant("1:9:A:G", sample, "0/1");
        Variant mergeVar = variantMerger.merge(var1, var2);
        StudyEntry se = mergeVar.getStudy(VariantTestUtils.STUDY_ID);
        assertEquals(Arrays.asList(sample), se.getOrderedSamplesName());
        String genotype = se.getSampleData(sample, VCFConstants.GENOTYPE_KEY.toString());
        assertEquals("0/1,0/2", genotype);
    }

    @Test
    public void testMergeOverlap_IN_SNP_MultiSampleAndRepeatSample() {
        // see https://github.com/opencb/biodata/issues/100
        String s1 = "S01";
        String s2 = "S02";
        Variant s1Var1 = VariantTestUtils.generateVariant("1:10::AT", s1, "0/1");
        Variant s2Var1 = VariantTestUtils.generateVariant("1:9:A:G", s2, "0/1");
        Variant s2Var2 = VariantTestUtils.generateVariant("1:10::AT", s2, "0/1");
        Variant mVar1 = variantMerger.merge(s1Var1, s2Var1);
        Variant mVar2 = variantMerger.merge(mVar1, s2Var2);
        StudyEntry se = mVar2.getStudy(VariantTestUtils.STUDY_ID);
//        assertEquals(Arrays.asList(s1), se.getOrderedSamplesName());
//        String genotype = se.getSampleData(s1, VCFConstants.GENOTYPE_KEY.toString());
//        assertEquals("0/1,0/2", genotype);
    }

    @Test
    public void testMergeOverlap_IN_SNP_FAIL() {
        thrown.expect(AssertionError.class);
        // Should only be merged once - before the inserted gap.
        checkOverlapNoSecondaries("1:10::AT", "1:10:A:G");
    }

    @Test
    public void testMergeOverlap_SNP_IN() {
        checkOverlapNoSecondaries("1:9:A:G", "1:10::AT");
    }

    @Test
    public void testMergeOverlap_SNP_IN_FAIL() {
        thrown.expect(AssertionError.class);
        // Should only be merged once - before the inserted gap.
        checkOverlapNoSecondaries("1:10:A:G", "1:10::AT");
    }

//    @Test
//    public void testMergeOverlap_2IN_2() {
//        checkOverlapNoSecondaries("1:9::ATGG", "1:11::GGG");
//    }

    @Test
    public void testMergeOverlap_SNP_DEL() {
        checkOverlapNoSecondaries("1:10:A:T", "1:10:A:");
    }

    @Test
    public void testMergeOverlap_DEL_SNP() {
        checkOverlapNoSecondaries("1:10:A:", "1:10:A:T");
    }

    @Test
    public void testMergeWithSecondary_2SNP() {
        Variant variant = VariantTestUtils.generateVariant("1",10,"A","G",VariantType.SNV,
                Arrays.asList("S02"),
                Arrays.asList("1/2"));
        variant.getStudies().get(0).setSecondaryAlternates(Arrays.asList(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV)));
        variantMerger.merge(var, variant);
        StudyEntry se = variantMerger.getStudy(var);
        assertEquals(Arrays.asList("S01", "S02"), se.getOrderedSamplesName());
        assertEquals(2, se.getSecondaryAlternates().size());
        assertEquals(Arrays.asList(lst("0/1"),lst("2/3")),
                onlyField(se.getSamplesData(), 0));
    }

    @Test
    public void testMergeWithSecondary_2SNP_2() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/1");
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:G", "S02", "1/2");
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "2/3");
    }

    @Test
    public void testMergeWithSecondaryWithOtherFields_2SNP_2() {
        Variant var1 = VariantTestUtils.generateVariantWithFormat("1:10:A:T", "GT:FT", "S01", "0/1", "PASS");
        Variant var2 = VariantTestUtils.generateVariantWithFormat("1:10:A:G", "GT:FT", "S02", "1/2", "noPASS");
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "2/3");
    }

    @Test
    public void testMergeWithSecondaryWithFileAttributes_2SNP_2() {
        Variant var1 = VariantTestUtils.generateVariantWithFormat("1:10:A:T", "GT", "S01", "0/1");
        Variant var2 = VariantTestUtils.generateVariantWithFormat("1:10:A:G", "GT", "S02", "1/2");
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "2/3");
    }

    @Test
    public void testMergeWithSecondaryWithOtherFormats() {
        Variant var1 = VariantTestUtils.generateVariantWithFormat("1:10:A:T", "GT:DP", "S01", "0/1", "4");
        Variant var2 = VariantTestUtils.generateVariantWithFormat("1:10:A:G", "GT:DP", "S02", "1/2", "5");
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        Variant mergedVariant = checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "2/3");
        StudyEntry studyEntry = mergedVariant.getStudies().get(0);
        assertEquals("GT:DP:FT", studyEntry.getFormatAsString());
        assertEquals("4", studyEntry.getSampleData("S01", "DP"));
        assertEquals("5", studyEntry.getSampleData("S02", "DP"));
    }

    @Test
    public void testMergeWithSecondaryWithOtherFormatsMissing() {
        variantMerger.setDefaultValue("DP", ".");
        variantMerger.setDefaultValue("GQ", ".");
        Variant var1 = VariantTestUtils.generateVariantWithFormat("1:10:A:T", "PASS1", 100F, "GT:DP", "S01", "0/1", "4");
        Variant var2 = VariantTestUtils.generateVariantWithFormat("1:10:A:G", "PASS2", 100F, "GT:GQ", "S02", "1/2", "0.2");
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        Variant mergedVariant = checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "2/3");
        StudyEntry studyEntry = mergedVariant.getStudies().get(0);
        assertEquals("GT:DP:FT:GQ", studyEntry.getFormatAsString());
        assertEquals("4", studyEntry.getSampleData("S01", "DP"));
        assertEquals("PASS1", studyEntry.getSampleData("S01", "FT"));
        assertEquals(".", studyEntry.getSampleData("S01", "GQ"));
        assertEquals(".", studyEntry.getSampleData("S02", "DP"));
        assertEquals("PASS2", studyEntry.getSampleData("S02", "FT"));
        assertEquals("0.2", studyEntry.getSampleData("S02", "GQ"));
    }

    @Test
    public void testMergeWithSecondaryWithOtherFormatsAndFT() {
        Variant var1 = VariantTestUtils.generateVariantWithFormat("1:10:A:T", "PASS1", 100F, "GT:DP:FT", "S01", "0/1", "4", "MyFilter1");
        Variant var2 = VariantTestUtils.generateVariantWithFormat("1:10:A:G,C", "PASS2", 100F, "GT:DP:FT", "S02", "1/2", "5", "MyFilter2");
        Variant mergedVariant = checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "2/3");
        StudyEntry studyEntry = mergedVariant.getStudies().get(0);
        assertEquals("GT:DP:FT", studyEntry.getFormatAsString());
        assertEquals("4", studyEntry.getSampleData("S01", "DP"));
        assertEquals("MyFilter1", studyEntry.getSampleData("S01", "FT"));
        assertEquals("5", studyEntry.getSampleData("S02", "DP"));
        assertEquals("MyFilter2", studyEntry.getSampleData("S02", "FT"));
    }

    @Test
    public void testUseWrongFormat() {
        variantMerger.setExpectedFormats(Arrays.asList("GT"));
        variantMerger.setExpectedFormats(Arrays.asList("DP"));
        variantMerger.setExpectedFormats(Arrays.asList("GT", "DP"));
        thrown.expect(IllegalArgumentException.class);
        variantMerger.setExpectedFormats(Arrays.asList("DP", "GT"));
    }

    @Test
    public void testMergeWithSecondaryWithExpectedFormats() {
        Variant var1 = VariantTestUtils.generateVariantWithFormat("1:10:A:T", "PASS1", 100F, "GT:DP:FT", "S01", "0/1", "4", "MyFilter1");
        Variant var2 = VariantTestUtils.generateVariantWithFormat("1:10:A:G,C", "PASS2", 100F, "GT:DP:GL", "S02", "1/2", "5", "...");
        variantMerger.setExpectedFormats(Arrays.asList("GT", "DP"));
        Variant mergedVariant = checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G", "1:10:A:C"), "2/3");
        StudyEntry studyEntry = mergedVariant.getStudies().get(0);
        assertEquals("GT:DP", studyEntry.getFormatAsString());
        assertEquals("4", studyEntry.getSampleData("S01", "DP"));
        assertEquals("5", studyEntry.getSampleData("S02", "DP"));
    }

    @Test
    public void testMergeWithSecondaryWithExpectedFormatsNoGT() {
        Variant var1 = VariantTestUtils.generateVariantWithFormat("1:10:A:T", "PASS1", 100F, "GT:DP:FT", "S01", "0/1", "4", "MyFilter1");
        Variant var2 = VariantTestUtils.generateVariantWithFormat("1:10:A:G,C", "PASS2", 100F, "GT:GL", "S02", "1/2", "...");
        variantMerger.setExpectedFormats(Arrays.asList("DP", "FT"));
        Variant mergedVariant = variantMerger.merge(var1, var2);
        StudyEntry studyEntry = mergedVariant.getStudies().get(0);
        assertEquals("DP:FT", studyEntry.getFormatAsString());
        assertEquals("4", studyEntry.getSampleData("S01", "DP"));
        assertEquals(variantMerger.getDefaultValue("DP"), studyEntry.getSampleData("S02", "DP"));
        assertEquals("MyFilter1", studyEntry.getSampleData("S01", "FT"));
        assertEquals("PASS2", studyEntry.getSampleData("S02", "FT"));
    }

    @Test
    public void testMergeWithSecondary_2SNP_3() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "1/2");
        var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "C", VariantType.SNV));
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:G", "S02", "0/1");
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:C", "1:10:A:G"), "0/3");
    }

    @Test
    public void testMergeWithSameSecondary_2SNP() {
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:T", "S01", "0/1");
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:G", "S02", "1/2");
        var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "T", VariantType.SNV));
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:G"), "2/1");
    }

    @Test
    public void testMergeWithSameSecondary_2SNP_2(){
        Variant var1 = VariantTestUtils.generateVariant("1:10:A:G", "S01", "1/2", "S02", "2/1");
        var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().add(new AlternateCoordinate("1", 10, 10, "A", "T", VariantType.SNV));
        Variant var2 = VariantTestUtils.generateVariant("1:10:A:T", "S03", "0/1", "S04", "1/1", "S05", "0/0");
        checkMergeVariants(var1, var2, Arrays.asList("1:10:A:T"), "0/2", "2/2", "0/0");
    }

    @Test
    public void testMergeMonoAllelicSameAlt() {
        variantMerger.merge(var, VariantTestUtils.generateVariant("1",10,"A","T",VariantType.SNV,
                Arrays.asList("S02"),
                Arrays.asList("1")));
        StudyEntry se = variantMerger.getStudy(var);
        assertEquals(Arrays.asList("S01", "S02"), se.getOrderedSamplesName());
        assertEquals(0, se.getSecondaryAlternates().size());
        assertEquals(Arrays.asList(lst("0/1"),lst("1")),
                onlyField(se.getSamplesData(), 0));
    }

    @Test
    public void testMergeMonoAllelicNocall() {
        variantMerger.merge(var, VariantTestUtils.generateVariant("1",10,"A","G",VariantType.SNV,
                Arrays.asList("S02"),
                Arrays.asList("./1")));
        StudyEntry se = variantMerger.getStudy(var);
        assertEquals(Arrays.asList("S01", "S02"), se.getOrderedSamplesName());
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals(Arrays.asList(lst("0/1"),lst("./2")),
                onlyField(se.getSamplesData(), 0));
    }

    @Test
    public void testMergeSnpBlock() {
        Variant v = VariantTestUtils.generateVariant("1:10:A:", "S01", "0/0");
        v.setType(VariantType.NO_VARIATION);
        v.setEnd(100);

        checkMergeVariants(VariantTestUtils.generateVariant("1:10:A:T", "S02", "0/1"), v, Collections.emptyList(), "0/0");
    }

    @Test
    public void testMergeSameSampleSameVariant() { // TODO check if this can happen and result is correct !!!
        thrown.expect(IllegalStateException.class);
        variantMerger.merge(var, VariantTestUtils.generateVariant("1", 10, "A", "T", VariantType.INDEL, Arrays.asList("S01"), Arrays.asList("0/1")));
        StudyEntry se = variantMerger.getStudy(var);
        assertEquals(1, se.getSecondaryAlternates().size());
//        // TODO not sure 1/2 is correct if the same individual has a variant with 0/1 and another variant with 0/2 overlapping each other
        assertEquals("0/1,0/2", se.getSamplesData().get(0).get(0));
    }

    @Test
    public void testMergeSameSampleDifferentVariant() { // TODO check if this can happen and result is correct !!!
        Variant res = variantMerger.merge(var, VariantTestUtils.generateVariant("1", 9, "AAA", "-", VariantType.INDEL, Arrays.asList("S01"), Arrays.asList("0/1")));
        StudyEntry se = res.getStudies().get(0);
        assertEquals(1, se.getSecondaryAlternates().size());
        assertEquals("0/1,0/2", se.getSampleData("S01",VCFConstants.GENOTYPE_KEY));
    }

    private List<String> lst(String str) {
        return Collections.singletonList(str);
    }

    @Test
    public void sameStartPosition(){
        assertTrue(VariantTestUtils.generateVariant("1", 10, "A", "T", VariantType.SNV).onSameStartPosition(VariantTestUtils.generateVariant("1", 10, "A", "T", VariantType.SNV)));
        assertFalse(VariantTestUtils.generateVariant("1", 10, "A", "T", VariantType.SNV).onSameStartPosition(VariantTestUtils.generateVariant("1", 11, "A", "T", VariantType.SNV)));
    }

    public void checkOverlapNoSecondaries(String varstr1, String varstr2) {
        checkOverlapNoSecondaries(varstr1, varstr2, "0/0", "0/0", "0/0");
        checkOverlapNoSecondaries(varstr1, varstr2, "0/0", "0/1", "0/2");
        checkOverlapNoSecondaries(varstr1, varstr2, "0/1", "1/1", "2/2");
        //Test with missing values
        checkOverlapNoSecondaries(varstr1, varstr2, "1/1", ".", ".");
        checkOverlapNoSecondaries(varstr1, varstr2, ".", "1/1", "2/2");
        checkOverlapNoSecondaries(varstr1, varstr2, "1/.", "1/.", "2/.");
        //Test with haploids
        checkOverlapNoSecondaries(varstr1, varstr2, "0", "1", "2");
        checkOverlapNoSecondaries(varstr1, varstr2, "0", "0", "0");
    }

    public void checkSameNoSecondaries(String varstr1) {
        checkSameNoSecondaries(varstr1, varstr1, "0/0", "0/0");
        checkSameNoSecondaries(varstr1, varstr1, "0/0", "0/1");
        checkSameNoSecondaries(varstr1, varstr1, "0/1", "1/1");
        //Test with missing values
        checkSameNoSecondaries(varstr1, varstr1, "1/1", ".");
        checkSameNoSecondaries(varstr1, varstr1, ".", "1/1");
        checkSameNoSecondaries(varstr1, varstr1, "1/.", "1/.");
        //Test with haploids
        checkSameNoSecondaries(varstr1, varstr1, "0", "1");
        checkSameNoSecondaries(varstr1, varstr1, "0", "0");
    }

    public Variant checkOverlapNoSecondaries(String varstr1, String varstr2, String gt1, String gt2, String gt2Merged) {
        return checkMergeVariants(varstr1, varstr2, gt1, gt2, gt2Merged);
    }

    public Variant checkSameNoSecondaries(String varstr1, String varstr2, String gt1, String gt2) {
        return checkMergeVariants(varstr1, varstr2, gt1, gt2, gt2);
    }

    public Variant checkMergeVariants(String varstr1, String varstr2, String gt1, String gt2, String gt2Merged) {
        return checkMergeVariantsNoSecondaries(
                VariantTestUtils.generateVariant(varstr1, "S01", gt1),
                VariantTestUtils.generateVariant(varstr2, "S02", gt2), gt2Merged);
    }

    public Variant checkMergeVariantsNoSecondaries(Variant var1, Variant var2, String ...expectedVar2Gts) {
        assertTrue(var1.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().isEmpty());
        assertTrue(var2.getStudy(VariantTestUtils.STUDY_ID).getSecondaryAlternates().isEmpty());

        String vars1 = var1.toString();
        String vars2 = var2.toString();
        if (vars1.equals(vars2)) {
            //Same Variant
            return checkMergeVariants(var1, var2, Collections.emptyList(), expectedVar2Gts);
        } else {
            //Overlapped variants
            return checkMergeVariants(var1, var2, Collections.singletonList(vars2), expectedVar2Gts);
        }
    }

    /**
     * Check if the merge of the two variants is done well. Assumes that the variants can be merged and the genotypes of
     * the first variant are not going to be modified.
     *
     * @param var1  First variant to be merged
     * @param var2  Second variant to be merged
     * @param expectedVar2Gts Expected genotypes of the second variant
     * @return  The merged variant, for additional checks
     */
    public Variant checkMergeVariants(Variant var1, Variant var2, List<String> expectedSecondaryAlternates, String ...expectedVar2Gts) {
        List<AlternateCoordinate> expectedAlternatesList = new LinkedList<>();
        for (String expectedAlternate : expectedSecondaryAlternates) {
            Variant other = new Variant(expectedAlternate);
            AlternateCoordinate alternate = new AlternateCoordinate(other.getChromosome(), other.getStart(), other.getEnd(),
                    other.getReference(), other.getAlternate(), other.getType());
            if (!expectedAlternatesList.contains(alternate)) {
                expectedAlternatesList.add(alternate);
            }
        }

        ArrayList<String> samples = new ArrayList<>();
        samples.addAll(var1.getStudy(VariantTestUtils.STUDY_ID).getOrderedSamplesName());
        samples.addAll(var2.getStudy(VariantTestUtils.STUDY_ID).getOrderedSamplesName());

        List<String> gtsVar1 = var1.getStudy(VariantTestUtils.STUDY_ID).getSamplesData().stream().map(strings -> strings.get(0)).collect(Collectors.toList());

        Variant mergeVar = variantMerger.merge(var1, var2);
        StudyEntry se = mergeVar.getStudy(VariantTestUtils.STUDY_ID);
        assertEquals(samples, se.getOrderedSamplesName());
        for (int i = 0; i < gtsVar1.size(); i++) {
            assertEquals(gtsVar1.get(i), se.getSampleData(samples.get(i), "GT"));
        }
        for (int i = 0; i < expectedVar2Gts.length; i++) {
            assertEqualGt(expectedVar2Gts[i], se.getSampleData(samples.get(gtsVar1.size() + i), "GT"));
        }

        assertEquals(new HashSet<>(expectedAlternatesList), new HashSet<>(se.getSecondaryAlternates()));

        return mergeVar;
    }

    private void assertEqualGt(String gta, String gtb) {
        Genotype a = new Genotype(gta);
        Genotype b = new Genotype(gtb);
        if (!a.isPhased()) {
            Arrays.sort(a.getAllelesIdx());
        }
        if (!b.isPhased()) {
            Arrays.sort(a.getAllelesIdx());
        }
        assertEquals(a.toString(), b.toString());
    }

    @Test
    public void overlapsWith() throws Exception {
        overlaps("2:100:C:A");
        overlaps("2:100:CC:AA");
        overlaps("2:100:C:AA");
        overlaps("2:100:CC:A");
        overlaps("2:100::A");
        notOverlaps("2:100::A", "2:99::A");
        overlaps("2:100::A", "2:100::CTTNNN");
        notOverlaps("2:100::A", "2:101::A");
        // At the position before and after, the insertion "overlaps" with a variant!
        notOverlaps("2:100::A", "2:98:C:A");
        overlaps("2:100::A", "2:99:C:A");
        notOverlaps("2:100::A", "2:100:C:A");
        notOverlaps("2:100::A", "2:101:C:A");
        notOverlaps("2:98:C:A", "2:100::A");
        overlaps("2:99:C:A", "2:100::A");
        notOverlaps("2:100:C:A", "2:100::A");
        notOverlaps("2:100::A", "2:98:A:C");
        notOverlaps("2:100::A", "2:101:A:C");
        notOverlaps("2:100::A", "2:99:A:C", false);
        notOverlaps("2:100::A","2:100:A:C", false);
    }

    public void overlaps(String variant) {
        overlaps(variant, variant);
    }

    public void overlaps(String variant, String otherVariant) {
        overlaps(variant, otherVariant, true);
    }

    public void overlaps(String variant, String otherVariant, boolean inclusive) {
        System.out.printf("%s %15s\n", variant, otherVariant);
        assertTrue("Variant '" + variant + "' should overlap with '" + otherVariant + "'",
                new Variant(variant).overlapWith(new Variant(otherVariant), inclusive));
    }

    public void notOverlaps(String variant, String otherVariant) {
        notOverlaps(variant, otherVariant, true);

    }
    public void notOverlaps(String variant, String otherVariant, boolean inclusive) {
        System.out.printf("%s %15s\n", variant, otherVariant);
        assertFalse("Variant '" + variant + "' should not overlap with '" + otherVariant + "'",
                new Variant(variant).overlapWith(new Variant(otherVariant), inclusive));

    }

    @Test
    public void hasAnyOverlapTest() {
        VariantNormalizer normalizer = new VariantNormalizer();
        Variant current = normalizer.apply(Collections.singletonList(VariantTestUtils.generateVariantWithFormat("2:102:C:T", "GT", "a", "0/0"))).get(0);
        Variant other = normalizer.apply(Collections.singletonList(VariantTestUtils.generateVariantWithFormat("2:100:CCCCC:ACCCC,TTTTT", "GT", "a", "0/0"))).get(0);
        assertTrue(VariantMerger.hasAnyOverlap(current, other));
        assertFalse(current.overlapWith(other, true));
    }

    @Test
    public void hasVariantOverlap() {
        Variant a = new Variant("12:39039799:-:AAAAAAGAGAG");
        Variant b = new Variant("12:39039797:-:AGAG");
        Variant c = new Variant("12:39039797:-:AGAG");

    }

}

redpajama_set_name: RedPajamaGithub


text:
#include "StdAfx.h"
#include "SkinSetting.h"
#include "About.h"

const TCHAR* const kSysBtnControlName = _T("SysButton");
const TCHAR* const kCloseButtonControlName = _T("closebtn");

const TCHAR* const kLogoControlName = _T("logo_btn");
const TCHAR* const kTitleControlName = _T("title");
const TCHAR* const kBackgroundControlName = _T("Background");
const TCHAR* const kClientRectControlName = _T("ClientRect");

CAbout::CAbout(HWND hWndParent,const RECT rc)
{

	m_bModal = false;

    Create(hWndParent, _T("About"), WS_POPUPWINDOW | WS_CAPTION | WS_DLGFRAME | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, WS_EX_TOOLWINDOW,rc, 0);

	MoveWindow(m_hWnd,rc.left, rc.top, rc.right, rc.bottom, FALSE);

	ShowWindow(true);

	//ShowModal();
}

CAbout::~CAbout(void)
{
}

LPCTSTR CAbout::GetWindowClassName() const
{
	return _T("AboutWindow");
}

void CAbout::OnFinalMessage(HWND hWnd)
{
	WindowImplBase::OnFinalMessage(hWnd);
	delete this;
}

void CAbout::OnPrepare(TNotifyUI& msg)
{

}
void CAbout::Notify(TNotifyUI& msg)
{
	if (_tcsicmp(msg.sType, _T("windowinit")) == 0)
	{
		OnPrepare(msg);
	}
	else if (_tcsicmp(msg.sType, _T("killfocus")) == 0)
	{

	}
	else if( msg.sType == _T("click") )
	{

		if (_tcsicmp(msg.pSender->GetName(), kCloseButtonControlName) == 0)
		{
			Close();
			return;
		}
	}
}

void CAbout::InitWindow()
{

}

CDuiString CAbout::GetSkinFile()
{
	return CSkinSetting::GetSkinFile();
}

CDuiString CAbout::GetSkinFolder()
{
	return CSkinSetting::GetSkinFolder();
}

UILIB_RESOURCETYPE CAbout::GetResourceType() const
{
	return  CSkinSetting::GetResourceType();
}

LPCTSTR CAbout::GetResourceID() const
{
	return  CSkinSetting::GetResourceID();
}

CDuiString CAbout::GetZIPFileName() const
{
	return CSkinSetting::GetZIPFileName();
}

DWORD CAbout::GetBkColor()
{
	CControlUI* background = m_PaintManager.FindControl(kBackgroundControlName);
	if (background != NULL)
		return background->GetBkColor();

	return 0;
}

void CAbout::SetBkColor(DWORD dwBackColor)
{
	CControlUI* background = m_PaintManager.FindControl(kBackgroundControlName);
	if (background != NULL)
	{
		background->SetBkImage(_T(""));
		background->SetBkColor(dwBackColor);
		background->NeedUpdate();
	}
}

void CAbout::SetBkImage(LPCTSTR szImageName)
{

	CControlUI* background = m_PaintManager.FindControl(kBackgroundControlName);
	if (background != NULL)
	{

		background->SetBkImage(szImageName);

	}
}

LRESULT CAbout::OnMouseMove(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{

	POINT pt;

	pt.x = GET_X_LPARAM(lParam); pt.y = GET_Y_LPARAM(lParam);

	RECT btnRect;

	CButtonUI* linkbtn;

	linkbtn = (CButtonUI*)m_PaintManager.FindControl(_T("www.131qz.com"));

	if (linkbtn != NULL)
	{

		btnRect = linkbtn->GetPos();

		if(pt.x > btnRect.left && pt.x < btnRect.right && pt.y > btnRect.top && pt.y < btnRect.bottom)
		{

			linkbtn->SetTextColor(0xffff0000);
			linkbtn->NeedUpdate();

		}else{

			linkbtn->SetTextColor(0xff0000ff);
			linkbtn->NeedUpdate();
		}

	}

	bHandled = FALSE;
	return 0;
}

LRESULT CAbout::OnMouseHover(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{

	bHandled = FALSE;
	return 0;
}

LRESULT CAbout::OnMouseLeave(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{

	bHandled = FALSE;

	return 0;
}

LRESULT CAbout::OnKillFocus(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	//Close();
	return 0;
}

LRESULT CAbout::OnNcActivate(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& bHandled)
{

	//wParamΪ0ʱ±íʾÊÇʧȥ½¹µã£¬Îª·Ç0ʱ±íʾµÃµ½½¹µã
	if (m_bModal)
	{
		if (! wParam)
		{

		}else{

		}
	}

	if( ::IsIconic(*this) ) bHandled = FALSE;
	return (wParam == 0) ? TRUE : FALSE;
}

DWORD CAbout::DoModal()
{
	if(! this->m_hWnd)
		return -1;
	m_bModal = true;
	return ShowModal();
}


text:
namespace paddle {
namespace framework {
namespace ir {

class InferenceProcessPass : public Pass {
 protected:
  void ApplyImpl(ir::Graph* graph) const override;
};

}  // namespace ir
}  // namespace framework
}  // namespace paddle


text:
import os

import pytest

from mfr.core.provider import ProviderMetadata
from mfr.core.exceptions import RendererError
from mfr.extensions.jamovi import JamoviRenderer

BASE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'files')

@pytest.fixture
def metadata():
    return ProviderMetadata('jamovi', '.omv', 'application/octet-stream', '1337',
                            'http://wb.osf.io/file/jamovi.omv?token=1337')

@pytest.fixture
def ok_path():
    return os.path.join(BASE_PATH, 'ok.omv')

@pytest.fixture
def ok_with_image_path():
    return os.path.join(BASE_PATH, 'ok-with-image.omv')

@pytest.fixture
def not_a_zip_file_path():
    return os.path.join(BASE_PATH, 'not-a-zip-file.omv')

@pytest.fixture
def no_manifest_path():
    return os.path.join(BASE_PATH, 'no-manifest.omv')

@pytest.fixture
def no_archive_version_in_manifest_path():
    return os.path.join(BASE_PATH, 'no-data-archive-version-in-manifest.omv')

@pytest.fixture
def archive_version_is_too_old_path():
    return os.path.join(BASE_PATH, 'data-archive-version-is-too-old.omv')

@pytest.fixture
def no_index_html_path():
    return os.path.join(BASE_PATH, 'no-index_html.omv')

@pytest.fixture
def contains_malicious_script_path():
    return os.path.join(BASE_PATH, 'contains-malicious-script.omv')

@pytest.fixture
def url():
    return 'http://wb.osf.io/file/jamovi.omv'

@pytest.fixture
def assets_url():
    return 'http://mfr.osf.io/assets'

@pytest.fixture
def export_url():
    return 'http://mfr.osf.io/export?url=' + url()

@pytest.fixture
def extension():
    return '.omv'

@pytest.fixture
def renderer(metadata, ok_path, url, assets_url, export_url):
    return JamoviRenderer(metadata, ok_path, url, assets_url, export_url)

class TestCodeJamoviRenderer:

    def test_render_jamovi(self, renderer):
        body = renderer.render()
        assert '
' in body

    def test_render_jamovi_with_image(self, metadata, ok_with_image_path, url, assets_url,
                                      export_url):
        renderer = JamoviRenderer(metadata, ok_with_image_path, url, assets_url, export_url)
        body = renderer.render()
        assert '
' in body
        assert '<img src="data:image/png;base64,' in body

    def test_render_jamovi_not_a_zip_file(self, metadata, not_a_zip_file_path, url, assets_url,
                                          export_url):
        try:
            renderer = JamoviRenderer(metadata, not_a_zip_file_path, url, assets_url, export_url)
            renderer.render()
        except RendererError:
            return

        assert False # should not get here

    def test_render_jamovi_no_manifest(self, metadata, no_manifest_path, url, assets_url,
                                       export_url):
        try:
            renderer = JamoviRenderer(metadata, no_manifest_path, url, assets_url, export_url)
            renderer.render()
        except RendererError:
            return

        assert False # should not get here

    def test_render_jamovi_no_archive_version_in_manifest(self, metadata,
                                                          no_archive_version_in_manifest_path,
                                                          url, assets_url, export_url):
        try:
            renderer = JamoviRenderer(metadata, no_archive_version_in_manifest_path, url,
                                      assets_url, export_url)
            renderer.render()
        except RendererError:
            return

        assert False # should not get here

    def test_render_jamovi_archive_is_too_old(self, metadata, archive_version_is_too_old_path, url,
                                              assets_url, export_url):
        try:
            renderer = JamoviRenderer(metadata, archive_version_is_too_old_path, url, assets_url,
                                      export_url)
            renderer.render()
        except RendererError:
            return

        assert False # should not get here

    def test_render_jamovi_no_index_html(self, metadata, no_index_html_path, url, assets_url,
                                         export_url):
        try:
            renderer = JamoviRenderer(metadata, no_index_html_path, url, assets_url, export_url)
            renderer.render()
        except RendererError:
            return

        assert False # should not get here

    def test_render_jamovi_contains_malicious_script(self, metadata, contains_malicious_script_path,
                                                     url, assets_url, export_url):
        renderer = JamoviRenderer(metadata, contains_malicious_script_path, url, assets_url,
                                  export_url)
        body = renderer.render()

        assert '


text:
<?php

namespace Raf\ChassorCoreBundle\Entity;

use Doctrine\ORM\EntityRepository;

/**
 * MailRepository
 *
 * This class was generated by the Doctrine ORM. Add your own custom
 * repository methods below.
 */
class MailRepository extends EntityRepository
{
}


text:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>Dialog Builder</title>
		<link href="css/style.css" rel="stylesheet" type="text/css" />
	</head>
	<body>
		<script src="js/bundle.js" type="text/javascript"></script>
		<script type="text/javascript"> require(['src/main']); </script>
	</body>
</html>


text:
#ifndef CHANNELSELECTION_H
#define CHANNELSELECTION_H

#include <QDialog>

#include "ui_addchannelsgroup.h"
#include "qlcinputsource.h"

class InputSelectionWidget;
class ChannelsGroup;
class Doc;

/** @addtogroup ui_fixtures
 * @{
 */

class AddChannelsGroup : public QDialog, public Ui_AddChannelsGroup
{
    Q_OBJECT
    Q_DISABLE_COPY(AddChannelsGroup)

    /*********************************************************************
     * Initialization
     *********************************************************************/
public:
    /**
     * Constructor
     *
     * @param parent The parent widget for the dialog
     * @param doc The QLC engine instance
     */
    AddChannelsGroup(QWidget* parent, Doc* doc, ChannelsGroup *group);
    ~AddChannelsGroup();

    /** @reimp */
    void accept();

private:
    Doc* m_doc;
    ChannelsGroup* m_chansGroup;
    InputSelectionWidget *m_inputSelWidget;

protected:
    int m_checkedChannels;
    bool m_isUpdating;

protected slots:
    void slotItemChecked(QTreeWidgetItem *item, int col);
};

/** @} */

#endif


text:
require 'spec_helper'

describe "clients/edit.html.erb" do
  before(:each) do
    @client = assign(:client, stub_model(Client,
      :name => "MyString",
      :slug => "MyString",
      :description => "MyString",
      :url => "MyString"
    ))
  end

  it "renders the edit client form" do
    render

    # Run the generator again with the --webrat flag if you want to use webrat matchers
    assert_select "form", :action => client_path(@client), :method => "post" do
      assert_select "input#client_name", :name => "client[name]"
      assert_select "input#client_slug", :name => "client[slug]"
      assert_select "input#client_description", :name => "client[description]"
      assert_select "input#client_url", :name => "client[url]"
    end
  end
end


text:
tt_content.<%= params.slugifiedContentName %> = COA
tt_content.<%= params.slugifiedContentName %> {
	5 = < lib.stdheader

	10 = COA
	10 {
		wrap = <div class="<%= params.slugifiedContentName %>Bloc">|

	}
}


text:
Manga.py
========

A set of small python scripts to download manga from online manga reading sites like Mangastream or Mangareader just from a link.

## Usage

The script download the manga pages in the folder where the script is kept.

In linux, `cd` to the directory and run the script with `python manga.py`. When prompted, use the link to the manga chapter to download.

In windows, run the script with python shell/IDLE.

In all cases, after parsing the image links,the scripts will download the chapter pages in the chapter. Enjoy!

## Requirements

You need to have python 2.7 installed to run this script. Also, [Requests](http://docs.python-requests.org/en/latest/) module is needed for the script to run, install it with `pip install requests` or `easy_install requests`. See their official link for more info.

You can also install the required packages with requirement.txt file, just use `pip install -r requirements.txt`

### Supported websites

The websites currently supported by Manga.py are listed below.

* <http://mangafox.me/>
* <http://www.mangainn.com/>
* <http://www.mangapanda.com>
* <http://mangareader.net/>
* <http://mangastream.com/> or <http://readms.com>

### Disclaimer

Use at your own liability. I suggest that you buy the manga when the volumes are out to support the writers and publishers.


text:
package org.apache.gora.store.impl;

import java.io.IOException;
import java.util.List;

import org.apache.gora.util.GoraException;
import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration;

/**
 * Metadata analyzer base class for one backend. The hierarchy based on this class
 * exposes some details of the backend.
 * This class is responsible of creating the connection to the backend with the given configuration,
 * getting the information about what Persistent entities could be created for that
 * backend based on the tables/namespaces/whatever of the backend , and telling what
 * fields exists in that table.
 *
 * Notice that the method {@link #getTableInfo(String persistentName)} returns an Object,
 * but each class extending this abstract class (for each backend) will return a specific
 * class with the information.
 */
public abstract class DataStoreMetadataAnalyzer implements Configurable {

  /**
   * Configuration from Hadoop/HBase/...
   */
  protected Configuration conf;

  /**
   * After been set the configuratin, this method is called.
   * This method should create the connection to the backend
   */
  public abstract void initialize() throws GoraException ;

  /**
   * This method allows to know the type of the backend to which it is connected.
   * Although this could be known at runtime when getting the instance from the DataStoreMetadataFactory,
   * it can be useful to have this method.
   *
   * @return The backend type. Recommended in CAPITAL LETTERS
   */
  public abstract String getType() ;

  /**
   * Gets the list of tables/namespaces/entities, that could be accesed as a Persistent Entity, from the backend.
   *
   * @return A list of the tables/namespaces/entities of the backend
   */
  public abstract List<String> getTablesNames() throws GoraException;

  /**
   * Returns the information of a table at the backend, information that could help building a schema
   * or mapping. Each backend has to implement a proper subclass adapted to the specific backend.
   *
   * @return A specific subclass depending on the backend type
   */
  public abstract Object getTableInfo(String tableName) throws GoraException ;

  public abstract void close() throws IOException ;

  @Override
  public void setConf(Configuration conf) {
    this.conf = conf;
  }

  @Override
  public Configuration getConf() {
    return conf;
  }
}


text:
package com.github.basking2.sdsai.itrex;

/**
 */
public class SExprRuntimeException extends RuntimeException {
    private static final long serialVersionUID = 3976798317524183454L;

    public SExprRuntimeException(String message, Throwable cause) {
        super(message, cause);
    }

    public SExprRuntimeException(Throwable cause) {
        super(cause);
    }

    public SExprRuntimeException(String message) {
        super(message);
    }
}


text:
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  #
  # Booleans
  # ==========
  def title?
    try(:title) && title.present?
  end

  def content?
    content.present?
  end

  def description?
    description.present?
  end

  def location?
    location.present?
  end
end


text:
import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.io.BufferedWriter;
import java.io.FileWriter;

import org.omg.CORBA.ORB;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import org.omg.PortableServer.POAManager;

public class LEDApplet extends Applet {

	/**
	 *
	 */
	private static final long serialVersionUID = 8895935158120036991L;

    int width = 16;
    int height = 16;
    Dimension windowSize = new Dimension((LEDImpl.NUMBER_OF_LEDS+1)*32, 32+16);

    LED led;
    ORB orb;
    public LEDApplet() {
		String IORfilename = "../ior";
		try {
		    // Initializing ORB/POA and server object
		    orb = ORB.init(new String[]{}, null);
		    org.omg.CORBA.Object rootpoa =
			orb.resolve_initial_references("RootPOA");
		    POA poa = POAHelper.narrow(rootpoa);
		    LEDImpl obj = new LEDImpl();
		    led = LEDHelper.narrow(poa.servant_to_reference(obj));
		    obj.addCallBackApplet(this);
		    obj.turnOn(2);

		    // Writing stringified IOR to file specified by IORfilename
		    String ior = orb.object_to_string(obj._this());
		    BufferedWriter bw = new BufferedWriter(new FileWriter(IORfilename));
		    bw.write(ior, 0, ior.length());
		    bw.flush();
		    bw.close();

		    // Server is now ready
		    POAManager poamgr = poa.the_POAManager();
		    poamgr.activate();
		    System.out.println("Server is now ready.\n") ;

		    new Thread(){
		    	public void run() {
		    		orb.run();
		    	}
		    }.start();
		}
		catch (Exception e) {
		    System.out.println("ERROR : " + e) ;
		    e.printStackTrace(System.out);
		}
    }

    @Override
	public void init() {
    	this.setSize(windowSize);
    	this.setBackground(Color.DARK_GRAY);
		super.init();
	}

	public void paint(Graphics g){
//        g.setColor(Color.DARK_GRAY);
//        g.fillRect(0, 0, windowSize.width - 1, windowSize.height - 1);

    	g.setColor(Color.GREEN);
        for(int i=0; i<LEDImpl.NUMBER_OF_LEDS; i++) {
        	int x = i*32 + 16;
        	int y = 16;

        	if (led.getState(i)) {
        		g.fillOval(x, y, width, height);
        	} else {
        		g.drawOval(x, y, width, height);
        	}

        }
    }

}


text:
package org.codelibs.fess.suggest.index.contents;

import java.io.IOException;
import java.util.List;

import org.codelibs.fess.suggest.converter.KatakanaToAlphabetConverter;
import org.codelibs.fess.suggest.converter.ReadingConverter;
import org.codelibs.fess.suggest.converter.ReadingConverterChain;
import org.codelibs.fess.suggest.entity.SuggestItem;
import org.codelibs.fess.suggest.index.contents.querylog.QueryLog;
import org.codelibs.fess.suggest.normalizer.Normalizer;
import org.codelibs.fess.suggest.normalizer.NormalizerChain;

import junit.framework.TestCase;

public class DefaultContentsParserTest extends TestCase {
    DefaultContentsParser defaultContentsParser = new DefaultContentsParser();
    String[] supportedFields = new String[] { "content", "title" };
    String[] tagFieldNames = new String[] { "label", "virtual_host" };
    String roleFieldName = "role";

    public void test_parseQueryLog() throws Exception {

        QueryLog queryLog = new QueryLog("content:検索エンジン", null);
        List<SuggestItem> items = defaultContentsParser.parseQueryLog(queryLog, supportedFields, tagFieldNames, roleFieldName,
                createDefaultReadingConverter(), createDefaultNormalizer());
        SuggestItem item = items.get(0);
        assertEquals("検索エンジン", item.getText());
        assertEquals(SuggestItem.Kind.QUERY, item.getKinds()[0]);
        assertEquals(1, item.getQueryFreq());
    }

    public void test_parseQueryLog2Word() throws Exception {
        QueryLog queryLog = new QueryLog("content:検索エンジン AND content:柿", null);
        List<SuggestItem> items = defaultContentsParser.parseQueryLog(queryLog, supportedFields, tagFieldNames, roleFieldName,
                createDefaultReadingConverter(), createDefaultNormalizer());
        assertEquals("検索エンジン 柿", items.get(0).getText());
    }

    public void test_parseQueryLogAndRole() throws Exception {
        QueryLog queryLog = new QueryLog("content:検索エンジン AND label:tag1", "role:role1");
        List<SuggestItem> items = defaultContentsParser.parseQueryLog(queryLog, supportedFields, tagFieldNames, roleFieldName,
                createDefaultReadingConverter(), createDefaultNormalizer());
        SuggestItem item = items.get(0);
        assertEquals("検索エンジン", item.getText());
        assertEquals("tag1", item.getTags()[0]);
        assertEquals("role1", item.getRoles()[0]);
    }

    protected ReadingConverter createDefaultReadingConverter() throws IOException {
        ReadingConverterChain chain = new ReadingConverterChain();
        // chain.addConverter(new KatakanaConverter());
        chain.addConverter(new KatakanaToAlphabetConverter());
        chain.init();
        return chain;
    }

    protected Normalizer createDefaultNormalizer() {
        // TODO
        return new NormalizerChain();
    }

}


text:
import { Platform, Dimensions } from 'react-native';

const deviceHeight = Dimensions.get('window').height;
export default () => {
  const theme = {
    flex: 1,
    backgroundColor: 'white',
    height: Platform.OS === 'ios' ? deviceHeight : deviceHeight - 20,
  };

  return theme;
};


text:
package main

import (
	"bufio"
	"flag"
	"fmt"
	"net"
	"os"
	"regexp"
	"strconv"

	mp "github.com/mackerelio/go-mackerel-plugin-helper"
)

var graphdef = map[string](mp.Graphs){
	"squid.requests": mp.Graphs{
		Label: "Squid Client Requests",
		Unit:  "integer",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "requests", Label: "Requests", Diff: true},
		},
	},
	"squid.cache_hit_ratio.5min": mp.Graphs{
		Label: "Squid Client Cache Hit Ratio (5min)",
		Unit:  "percentage",
		Metrics: [](mp.Metrics){
			mp.Metrics{Name: "request_ratio", Label: "Request Ratio", Diff: false},
			mp.Metrics{Name: "byte_ratio", Label: "Byte Ratio", Diff: false},
		},
	},
}

// SquidPlugin mackerel plugin for squid
type SquidPlugin struct {
	Target   string
	Tempfile string
}

// FetchMetrics interface for mackerelplugin
func (m SquidPlugin) FetchMetrics() (map[string]interface{}, error) {
	conn, err := net.Dial("tcp", m.Target)
	if err != nil {
		return nil, err
	}
	fmt.Fprintln(conn, "GET cache_object://"+m.Target+"/info HTTP/1.0\n\n")
	scanner := bufio.NewScanner(conn)

	stat := make(map[string]interface{})
	//regexpmap := make(map[string]*regexp.Regexp)
	regexpmap := map[*regexp.Regexp]string{
		regexp.MustCompile("Number of HTTP requests received:\t([0-9]+)"): "requests",
		// version 2
		regexp.MustCompile("Request Hit Ratios:\t5min: ([0-9\\.]+)%"): "request_ratio",
		regexp.MustCompile("Byte Hit Ratios:\t5min: ([0-9\\.]+)%"):    "byte_ratio",
		// version 3
		regexp.MustCompile("Hits as % of all requests:\t5min: ([0-9\\.]+)%"): "request_ratio",
		regexp.MustCompile("Hits as % of bytes sent:\t5min: ([0-9\\.]+)%"):   "byte_ratio",
	}

	for scanner.Scan() {
		line := scanner.Text()
		s := string(line)

		for rexp, key := range regexpmap {
			match := rexp.FindStringSubmatch(s)
			if match == nil {
				continue
			}

			stat[key], err = strconv.ParseFloat(match[1], 64)
			if err != nil {
				return nil, err
			}
			break
		}
	}

	return stat, err
}

// GraphDefinition interface for mackerelplugin
func (m SquidPlugin) GraphDefinition() map[string](mp.Graphs) {
	return graphdef
}

func main() {
	optHost := flag.String("host", "localhost", "Hostname")
	optPort := flag.String("port", "3128", "Port")
	optTempfile := flag.String("tempfile", "", "Temp file name")
	flag.Parse()

	var squid SquidPlugin
	squid.Target = fmt.Sprintf("%s:%s", *optHost, *optPort)
	helper := mp.NewMackerelPlugin(squid)

	if *optTempfile != "" {
		helper.Tempfile = *optTempfile
	} else {
		helper.Tempfile = fmt.Sprintf("/tmp/mackerel-plugin-squid-%s-%s", *optHost, *optPort)
	}

	if os.Getenv("MACKEREL_AGENT_PLUGIN_META") != "" {
		helper.OutputDefinitions()
	} else {
		helper.OutputValues()
	}
}


text:
namespace MVC {

export namespace Directives {

export const REGISTRY: DirectiveConstructorInterface[] = [
  WithDirective,
  ForDirective,
  IfDirective,
  ControllerDirective,
  IncludeDirective,
  ComponentDirective,
  OnDirective,
  BindDirective,
  RootDirective,
];

}  // namespace Directives

function _bind(directiveIndex: number, model: Model, node: Node, controllers: ControllerFrame): DirectiveInterface {
  const registry = MVC.Directives.REGISTRY;
  const DirectiveConstructor = registry[directiveIndex % registry.length];
  if (DirectiveConstructor.matches(node)) {
    return new DirectiveConstructor((model, node, controllers) => {
      return _bind(directiveIndex + 1, model, node, controllers);
    }, model, node, controllers);
  } else {
    return _bind(directiveIndex + 1, model, node, controllers);
  }
}

export function bind(model: Dictionary, view: Element): void {
  _bind(0, Model.create(model), view, ControllerFrame.create());
}

export function bindBody(model: Dictionary): void {
  MVC.bind(model, document.body);
}

}  // namespace MVC


text:
#ifndef BITFIELD
#define BITFIELD

struct BitField {
  char a;
  double b;
  int c;
  int d : 3;
  int e : 4;
  unsigned int f : 2;
};

struct Mirror {
  char a;
  double b;
  int c;
  int d;
  int e;
  unsigned int f;
};

struct BitField toBitfield(const struct Mirror *mirror);
struct Mirror toMirror(const struct BitField *bf);

#endif /* BITFIELD */


text:
using namespace asdf;

minimap_widget_t::minimap_widget_t(asdf::hexmap::editor::editor_t& _edtior, QWidget *parent) :
    QOpenGLWidget(parent)
  , map_data(_edtior.map_data)
{
    hexmap_widget = static_cast<MainWindow*>(parent)->hexmap_widget;
}

minimap_widget_t::~minimap_widget_t()
{
}

QSize minimap_widget_t::sizeHint() const
{
    return QSize(150, 150);
}

void minimap_widget_t::initializeGL()
{
    using namespace asdf;
    using namespace hexmap;

    ASSERT(app.renderer, "asdf app renderer should exist by now");

    //apparently this func gets called again when the widget is in a dock widget that gets undocked
    if(!gl_state)
    {
        void* qt_gl_context = reinterpret_cast<void*>(context());
        gl_state = std::make_unique<gl_state_t>(qt_gl_context);
        GL_State.set_current_state_machine(*(gl_state.get()));

        rendered_map = std::make_unique<ui::hex_map_t>(map_data);

        minimap = std::make_unique<ui::minimap_t>(*(rendered_map.get()));

        emit initialized();
    }
}

void minimap_widget_t::resizeGL(int w, int h){
    ASSERT(minimap, "");
    minimap->render_target.texture.write(nullptr, w, h); //resize render target texture

    auto& camera = rendered_map->camera;
    camera.set_aspect_ratio(w, h);
    camera.viewport = asdf::viewport_for_size_aspect(map_data.hex_grid.size_units(), camera.aspect_ratio);

    is_dirty = true;
}

void minimap_widget_t::paintGL(){
    //ASSERT(!CheckGLError(), "GL Error");
    CheckGLError(); //clear gl errors. I think QT is doing something stupid

    //set global GL_State proxy object to point to this context
    ASSERT(reinterpret_cast<void*>(context()) == gl_state->gl_context, "wtf? the GL context changed");
    GL_State.set_current_state_machine(*(gl_state.get()));

    //put the widget's fbo at the bottom of the stack
    auto const& t = minimap->render_target.texture;
    scoped_fbo_t scoped(defaultFramebufferObject(), 0,0, t.width, t.height);

    glDisable(GL_DEPTH_TEST);

    auto& gl_clear_color = asdf::app.renderer->gl_clear_color;
    glClearColor(gl_clear_color.r
                       , gl_clear_color.g
                       , gl_clear_color.b
                       , gl_clear_color.a);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glDisable(GL_CULL_FACE);

    if(is_dirty)
    {
        minimap->rebuild();
        is_dirty = false;
    }

    minimap->render();
}

void minimap_widget_t::mousePressEvent(QMouseEvent*){
}

void minimap_widget_t::mouseReleaseEvent(QMouseEvent*){
}

void minimap_widget_t::mouseMoveEvent(QMouseEvent*){
}

void minimap_widget_t::wheelEvent(QWheelEvent*){
}