private void adjustPhasedConsequenceTypes(Object[] variantArray) {
        Variant variant0 = (Variant) variantArray[0];
        Variant variant1 = null;
        Variant variant2 = null;

        boolean variant0DisplayCTNeedsUpdate = false;
        boolean variant1DisplayCTNeedsUpdate = false;
        boolean variant2DisplayCTNeedsUpdate = false;

        for (ConsequenceType consequenceType1 : variant0.getAnnotation().getConsequenceTypes()) {
            ProteinVariantAnnotation newProteinVariantAnnotation = null;
            // Check if this is a coding consequence type. Also this consequence type may have been already
            // updated if there are 3 consecutive phased SNVs affecting the same codon.
            if (isCoding(consequenceType1)
                    && !transcriptAnnotationUpdated(variant0, consequenceType1.getEnsemblTranscriptId())) {
                variant1 = (Variant) variantArray[1];
                ConsequenceType consequenceType2
                        = findCodingOverlappingConsequenceType(consequenceType1, variant1.getAnnotation().getConsequenceTypes());
                // The two first variants affect the same codon
                if (consequenceType2 != null) {
                    // WARNING: assumes variants are sorted according to their coordinates
                    int cdnaPosition = consequenceType1.getCdnaPosition();
                    int cdsPosition = consequenceType1.getCdsPosition();
                    String codon = null;
//                    String alternateAA = null;
                    List<SequenceOntologyTerm> soTerms = null;
                    ConsequenceType consequenceType3 = null;
                    variant2 = null;
                    // Check if the third variant also affects the same codon
                    if (variantArray.length > 2) {
                        variant2 = (Variant) variantArray[2];
                        consequenceType3
                                = findCodingOverlappingConsequenceType(consequenceType2, variant2.getAnnotation().getConsequenceTypes());
                    }
                    // The three SNVs affect the same codon
                    if (consequenceType3 != null) {
                        String referenceCodon = consequenceType1.getCodon().split("/")[0].toUpperCase();
                        // WARNING: assumes variants are sorted according to their coordinates
                        String alternateCodon = variant0.getAlternate() + variant1.getAlternate()
                                + variant2.getAlternate();
                        codon = referenceCodon + "/" + alternateCodon;
//                            alternateAA = VariantAnnotationUtils.CODON_TO_A.get(alternateCodon);
                        soTerms = updatePhasedSoTerms(consequenceType1.getSequenceOntologyTerms(),
                                String.valueOf(referenceCodon), String.valueOf(alternateCodon),
                                variant1.getChromosome().equals("MT"));

                        // Update consequenceType3
                        consequenceType3.setCdnaPosition(cdnaPosition);
                        consequenceType3.setCdsPosition(cdsPosition);
                        consequenceType3.setCodon(codon);
                        //                        consequenceType3.getProteinVariantAnnotation().setAlternate(alternateAA);
                        newProteinVariantAnnotation = getProteinAnnotation(consequenceType3);
                        consequenceType3.setProteinVariantAnnotation(newProteinVariantAnnotation);
                        consequenceType3.setSequenceOntologyTerms(soTerms);

                        // Flag these transcripts as already updated for this variant
                        flagTranscriptAnnotationUpdated(variant2, consequenceType1.getEnsemblTranscriptId());

                        variant2DisplayCTNeedsUpdate = true;

                        // Only the two first SNVs affect the same codon
                    } else {
                        int codonIdx1 = getUpperCaseLetterPosition(consequenceType1.getCodon().split("/")[0]);
                        int codonIdx2 = getUpperCaseLetterPosition(consequenceType2.getCodon().split("/")[0]);

                        // Set referenceCodon  and alternateCodon leaving only the nts that change in uppercase.
                        // Careful with upper/lower case letters
                        char[] referenceCodonArray = consequenceType1.getCodon().split("/")[0].toLowerCase().toCharArray();
                        referenceCodonArray[codonIdx1] = Character.toUpperCase(referenceCodonArray[codonIdx1]);
                        referenceCodonArray[codonIdx2] = Character.toUpperCase(referenceCodonArray[codonIdx2]);
                        char[] alternateCodonArray = referenceCodonArray.clone();
                        alternateCodonArray[codonIdx1] = variant0.getAlternate().toUpperCase().toCharArray()[0];
                        alternateCodonArray[codonIdx2] = variant1.getAlternate().toUpperCase().toCharArray()[0];

                        codon = String.valueOf(referenceCodonArray) + "/" + String.valueOf(alternateCodonArray);
//                            alternateAA = VariantAnnotationUtils.CODON_TO_A.get(String.valueOf(alternateCodonArray).toUpperCase());
                        soTerms = updatePhasedSoTerms(consequenceType1.getSequenceOntologyTerms(),
                                String.valueOf(referenceCodonArray).toUpperCase(),
                                String.valueOf(alternateCodonArray).toUpperCase(), variant1.getChromosome().equals("MT"));
                    }

                    // Update consequenceType1 & 2
                    consequenceType1.setCodon(codon);
                    //                    consequenceType1.getProteinVariantAnnotation().setAlternate(alternateAA);
                    consequenceType1.setProteinVariantAnnotation(newProteinVariantAnnotation == null
                            ? getProteinAnnotation(consequenceType1) : newProteinVariantAnnotation);
                    consequenceType1.setSequenceOntologyTerms(soTerms);
                    consequenceType2.setCdnaPosition(cdnaPosition);
                    consequenceType2.setCdsPosition(cdsPosition);
                    consequenceType2.setCodon(codon);
                    //                    consequenceType2.getProteinVariantAnnotation().setAlternate(alternateAA);
                    consequenceType2.setProteinVariantAnnotation(consequenceType1.getProteinVariantAnnotation());
                    consequenceType2.setSequenceOntologyTerms(soTerms);

                    // Flag these transcripts as already updated for this variant
                    flagTranscriptAnnotationUpdated(variant0, consequenceType1.getEnsemblTranscriptId());
                    flagTranscriptAnnotationUpdated(variant1, consequenceType1.getEnsemblTranscriptId());

                    variant0DisplayCTNeedsUpdate = true;
                    variant1DisplayCTNeedsUpdate = true;
                }
            }
        }

        if (variant0DisplayCTNeedsUpdate) {
            variant0.getAnnotation()
                    .setDisplayConsequenceType(getMostSevereConsequenceType(variant0.getAnnotation()
                            .getConsequenceTypes()));
        }
        if (variant1DisplayCTNeedsUpdate) {
            variant1.getAnnotation()
                    .setDisplayConsequenceType(getMostSevereConsequenceType(variant1.getAnnotation()
                            .getConsequenceTypes()));
        }
        if (variant2DisplayCTNeedsUpdate) {
            variant2.getAnnotation()
                    .setDisplayConsequenceType(getMostSevereConsequenceType(variant2.getAnnotation()
                            .getConsequenceTypes()));
        }
    }
private void adjustPhasedConsequenceTypes ( Object [ ] variantArray ) { Variant variant0 = ( Variant ) variantArray [ 0 ] ; Variant variant1 = null ; Variant variant2 = null ; boolean variant0DisplayCTNeedsUpdate = false ; boolean variant1DisplayCTNeedsUpdate = false ; boolean variant2DisplayCTNeedsUpdate = false ; for ( ConsequenceType consequenceType1 : variant0 . getAnnotation ( ) . getConsequenceTypes ( ) ) { ProteinVariantAnnotation newProteinVariantAnnotation = null ; if ( isCoding ( consequenceType1 ) && ! transcriptAnnotationUpdated ( variant0 , consequenceType1 . getEnsemblTranscriptId ( ) ) ) { variant1 = ( Variant ) variantArray [ 1 ] ; ConsequenceType consequenceType2 = findCodingOverlappingConsequenceType ( consequenceType1 , variant1 . getAnnotation ( ) . getConsequenceTypes ( ) ) ; if ( consequenceType2 != null ) { int cdnaPosition = consequenceType1 . getCdnaPosition ( ) ; int cdsPosition = consequenceType1 . getCdsPosition ( ) ; String codon = null ; List < SequenceOntologyTerm > soTerms = null ; ConsequenceType consequenceType3 = null ; variant2 = null ; if ( variantArray . length > 2 ) { variant2 = ( Variant ) variantArray [ 2 ] ; consequenceType3 = findCodingOverlappingConsequenceType ( consequenceType2 , variant2 . getAnnotation ( ) . getConsequenceTypes ( ) ) ; } if ( consequenceType3 != null ) { String referenceCodon = consequenceType1 . getCodon ( ) . split ( "/" ) [ 0 ] . toUpperCase ( ) ; String alternateCodon = variant0 . getAlternate ( ) + variant1 . getAlternate ( ) + variant2 . getAlternate ( ) ; codon = referenceCodon + "/" + alternateCodon ; soTerms = updatePhasedSoTerms ( consequenceType1 . getSequenceOntologyTerms ( ) , String . valueOf ( referenceCodon ) , String . valueOf ( alternateCodon ) , variant1 . getChromosome ( ) . equals ( "MT" ) ) ; consequenceType3 . setCdnaPosition ( cdnaPosition ) ; consequenceType3 . setCdsPosition ( cdsPosition ) ; consequenceType3 . setCodon ( codon ) ; newProteinVariantAnnotation = getProteinAnnotation ( consequenceType3 ) ; consequenceType3 . setProteinVariantAnnotation ( newProteinVariantAnnotation ) ; consequenceType3 . setSequenceOntologyTerms ( soTerms ) ; flagTranscriptAnnotationUpdated ( variant2 , consequenceType1 . getEnsemblTranscriptId ( ) ) ; variant2DisplayCTNeedsUpdate = true ; } else { int codonIdx1 = getUpperCaseLetterPosition ( consequenceType1 . getCodon ( ) . split ( "/" ) [ 0 ] ) ; int codonIdx2 = getUpperCaseLetterPosition ( consequenceType2 . getCodon ( ) . split ( "/" ) [ 0 ] ) ; char [ ] referenceCodonArray = consequenceType1 . getCodon ( ) . split ( "/" ) [ 0 ] . toLowerCase ( ) . toCharArray ( ) ; referenceCodonArray [ codonIdx1 ] = Character . toUpperCase ( referenceCodonArray [ codonIdx1 ] ) ; referenceCodonArray [ codonIdx2 ] = Character . toUpperCase ( referenceCodonArray [ codonIdx2 ] ) ; char [ ] alternateCodonArray = referenceCodonArray . clone ( ) ; alternateCodonArray [ codonIdx1 ] = variant0 . getAlternate ( ) . toUpperCase ( ) . toCharArray ( ) [ 0 ] ; alternateCodonArray [ codonIdx2 ] = variant1 . getAlternate ( ) . toUpperCase ( ) . toCharArray ( ) [ 0 ] ; codon = String . valueOf ( referenceCodonArray ) + "/" + String . valueOf ( alternateCodonArray ) ; soTerms = updatePhasedSoTerms ( consequenceType1 . getSequenceOntologyTerms ( ) , String . valueOf ( referenceCodonArray ) . toUpperCase ( ) , String . valueOf ( alternateCodonArray ) . toUpperCase ( ) , variant1 . getChromosome ( ) . equals ( "MT" ) ) ; } consequenceType1 . setCodon ( codon ) ; consequenceType1 . setProteinVariantAnnotation ( newProteinVariantAnnotation == null ? getProteinAnnotation ( consequenceType1 ) : newProteinVariantAnnotation ) ; consequenceType1 . setSequenceOntologyTerms ( soTerms ) ; consequenceType2 . setCdnaPosition ( cdnaPosition ) ; consequenceType2 . setCdsPosition ( cdsPosition ) ; consequenceType2 . setCodon ( codon ) ; consequenceType2 . setProteinVariantAnnotation ( consequenceType1 . getProteinVariantAnnotation ( ) ) ; consequenceType2 . setSequenceOntologyTerms ( soTerms ) ; flagTranscriptAnnotationUpdated ( variant0 , consequenceType1 . getEnsemblTranscriptId ( ) ) ; flagTranscriptAnnotationUpdated ( variant1 , consequenceType1 . getEnsemblTranscriptId ( ) ) ; variant0DisplayCTNeedsUpdate = true ; variant1DisplayCTNeedsUpdate = true ; } } } if ( variant0DisplayCTNeedsUpdate ) { variant0 . getAnnotation ( ) . setDisplayConsequenceType ( getMostSevereConsequenceType ( variant0 . getAnnotation ( ) . getConsequenceTypes ( ) ) ) ; } if ( variant1DisplayCTNeedsUpdate ) { variant1 . getAnnotation ( ) . setDisplayConsequenceType ( getMostSevereConsequenceType ( variant1 . getAnnotation ( ) . getConsequenceTypes ( ) ) ) ; } if ( variant2DisplayCTNeedsUpdate ) { variant2 . getAnnotation ( ) . setDisplayConsequenceType ( getMostSevereConsequenceType ( variant2 . getAnnotation ( ) . getConsequenceTypes ( ) ) ) ; } }
}