def build_altseq(self):
        """given a variant and a sequence, incorporate the variant and return the new sequence

        Data structure returned is analogous to the data structure used to return the variant sequence,
        but with an additional parameter denoting the start of a frameshift that should affect all bases
        downstream.

        :returns variant sequence data
        :rtype list of dictionaries
        """
        NOT_CDS = "not_cds_variant"
        WHOLE_GENE_DELETED = "whole_gene_deleted"

        type_map = {
            NARefAlt: self._incorporate_delins,
            Dup: self._incorporate_dup,
            Inv: self._incorporate_inv,
            Repeat: self._incorporate_repeat,
            NOT_CDS: self._create_alt_equals_ref_noncds,
            WHOLE_GENE_DELETED: self._create_no_protein
        }

        # should loop over each allele rather than assume only 1 variant; return a list for now
        alt_data = []

        variant_location = self._get_variant_region()

        if variant_location == self.EXON:
            edit_type = type(self._var_c.posedit.edit)
        elif variant_location == self.INTRON:
            edit_type = NOT_CDS
        elif variant_location == self.T_UTR:
            edit_type = NOT_CDS
        elif variant_location == self.F_UTR:
            # TODO: handle case where variant introduces a Met (new start)
            edit_type = NOT_CDS
        elif variant_location == self.WHOLE_GENE:
            if self._var_c.posedit.edit.type == "del":
                edit_type = WHOLE_GENE_DELETED
            elif self._var_c.posedit.edit.type == "dup":
                _logger.warning(
                    "Whole-gene duplication; consequence assumed to not affect protein product")
                edit_type = NOT_CDS
            elif self._var_c.posedit.edit.type == "inv":
                _logger.warning(
                    "Whole-gene inversion; consequence assumed to not affect protein product")
                edit_type = NOT_CDS
            else:
                edit_type = NOT_CDS
        else:    # should never get here
            raise ValueError("value_location = {}".format(variant_location))

        try:
            this_alt_data = type_map[edit_type]()
        except KeyError:
            raise NotImplementedError("c to p translation unsupported for {} type {}".format(
                self._var_c, edit_type))

        # get the start of the "terminal" frameshift (i.e. one never "cancelled out")
        this_alt_data = self._get_frameshift_start(this_alt_data)
        alt_data.append(this_alt_data)
        if DBG:
            print(this_alt_data.transcript_sequence)

        return alt_data
given a variant and a sequence, incorporate the variant and return the new sequence

        Data structure returned is analogous to the data structure used to return the variant sequence,
        but with an additional parameter denoting the start of a frameshift that should affect all bases
        downstream.

        :returns variant sequence data
        :rtype list of dictionaries