@DataProvider(name = "TrimCigarData")
    public Object[][] makeTrimCigarData() {
        List<Object[]> tests = new ArrayList<>();
        for ( final CigarOperator op : Arrays.asList(CigarOperator.D, CigarOperator.EQ, CigarOperator.X, CigarOperator.M) ) {
            for ( int myLength = 1; myLength < 6; myLength++ ) {
                for ( int start = 0; start < myLength - 1; start++ ) {
                    for ( int end = start; end < myLength; end++ ) {
                        final int length = end - start + 1;
                        final List<CigarOperator> padOps = Arrays.asList(CigarOperator.D, CigarOperator.M);
                        for ( final CigarOperator padOp: padOps) {
                            for ( int leftPad = 0; leftPad < 2; leftPad++ ) {
                                for ( int rightPad = 0; rightPad < 2; rightPad++ ) {
                                    tests.add(new Object[]{
                                            (leftPad > 0 ? leftPad + padOp.toString() : "") + myLength + op.toString() + (rightPad > 0 ? rightPad + padOp.toString() : ""),
                                            start + leftPad,
                                            end + leftPad,
                                            length + op.toString()});
                                }
                            }
                        }
                    }
                }
            }
        }
        for ( final int leftPad : Arrays.asList(0, 1, 2, 5) ) {
            for ( final int rightPad : Arrays.asList(0, 1, 2, 5) ) {
                final int length = leftPad + rightPad;
                if ( length > 0 ) {
                    for ( final int insSize : Arrays.asList(1, 10) ) {
                        for ( int start = 0; start <= leftPad; start++ ) {
                            for ( int stop = leftPad; stop < length; stop++ ) {
                                final int leftPadRemaining = leftPad - start;
                                final int rightPadRemaining = stop - leftPad + 1;
                                final String insC = insSize + "I";
                                tests.add(new Object[]{
                                        leftPad + "M" + insC + rightPad + "M",
                                        start,
                                        stop,
                                        (leftPadRemaining > 0 ? leftPadRemaining + "M" : "") + insC + (rightPadRemaining > 0 ? rightPadRemaining + "M" : "")
                                });
                            }
                        }
                    }
                }
            }
        }
        tests.add(new Object[]{"3M2D4M", 0, 8, "3M2D4M"});
        tests.add(new Object[]{"3M2D4M", 2, 8, "1M2D4M"});
        tests.add(new Object[]{"3M2D4M", 2, 6, "1M2D2M"});
        tests.add(new Object[]{"3M2D4M", 3, 6, "2D2M"});
        tests.add(new Object[]{"3M2D4M", 4, 6, "1D2M"});
        tests.add(new Object[]{"3M2D4M", 5, 6, "2M"});
        tests.add(new Object[]{"3M2D4M", 6, 6, "1M"});
        tests.add(new Object[]{"2M3I4M", 0, 5, "2M3I4M"});
        tests.add(new Object[]{"2M3I4M", 1, 5, "1M3I4M"});
        tests.add(new Object[]{"2M3I4M", 1, 4, "1M3I3M"});
        tests.add(new Object[]{"2M3I4M", 2, 4, "3I3M"});
        tests.add(new Object[]{"2M3I4M", 2, 3, "3I2M"});
        tests.add(new Object[]{"2M3I4M", 2, 2, "3I1M"});
        tests.add(new Object[]{"2M3I4M", 3, 4, "2M"});
        tests.add(new Object[]{"2M3I4M", 3, 3, "1M"});
        tests.add(new Object[]{"2M3I4M", 4, 4, "1M"});
        // this doesn't work -- but I'm not sure it should
        //        tests.add(new Object[]{"2M3I4M", 2, 1, "3I"});
        return tests.toArray(new Object[][]{});
    }
@DataProvider(name = "TrimCigarData")
    public Object[][] makeTrimCigarData() {
        List<Object[]> tests = new ArrayList<>();
        for ( final CigarOperator op : Arrays.asList(CigarOperator.D, CigarOperator.EQ, CigarOperator.X, CigarOperator.M) ) {
            for ( int myLength = 1; myLength < 6; myLength++ ) {
                for ( int start = 0; start < myLength - 1; start++ ) {
                    for ( int end = start; end < myLength; end++ ) {
                        final int length = end - start + 1;
                        final List<CigarOperator> padOps = Arrays.asList(CigarOperator.D, CigarOperator.M);
                        for ( final CigarOperator padOp: padOps) {
                            for ( int leftPad = 0; leftPad < 2; leftPad++ ) {
                                for ( int rightPad = 0; rightPad < 2; rightPad++ ) {
                                    tests.add(new Object[]{
                                            (leftPad > 0 ? leftPad + padOp.toString() : "") + myLength + op.toString() + (rightPad > 0 ? rightPad + padOp.toString() : ""),
                                            start + leftPad,
                                            end + leftPad,
                                            length + op.toString()});
                                }
                            }
                        }
                    }
                }
            }
        }
        for ( final int leftPad : Arrays.asList(0, 1, 2, 5) ) {
            for ( final int rightPad : Arrays.asList(0, 1, 2, 5) ) {
                final int length = leftPad + rightPad;
                if ( length > 0 ) {
                    for ( final int insSize : Arrays.asList(1, 10) ) {
                        for ( int start = 0; start <= leftPad; start++ ) {
                            for ( int stop = leftPad; stop < length; stop++ ) {
                                final int leftPadRemaining = leftPad - start;
                                final int rightPadRemaining = stop - leftPad + 1;
                                final String insC = insSize + "I";
                                tests.add(new Object[]{
                                        leftPad + "M" + insC + rightPad + "M",
                                        start,
                                        stop,
                                        (leftPadRemaining > 0 ? leftPadRemaining + "M" : "") + insC + (rightPadRemaining > 0 ? rightPadRemaining + "M" : "")
                                });
                            }
                        }
                    }
                }
            }
        }
        tests.add(new Object[]{"3M2D4M", 0, 8, "3M2D4M"});
        tests.add(new Object[]{"3M2D4M", 2, 8, "1M2D4M"});
        tests.add(new Object[]{"3M2D4M", 2, 6, "1M2D2M"});
        tests.add(new Object[]{"3M2D4M", 3, 6, "2D2M"});
        tests.add(new Object[]{"3M2D4M", 4, 6, "1D2M"});
        tests.add(new Object[]{"3M2D4M", 5, 6, "2M"});
        tests.add(new Object[]{"3M2D4M", 6, 6, "1M"});
        tests.add(new Object[]{"2M3I4M", 0, 5, "2M3I4M"});
        tests.add(new Object[]{"2M3I4M", 1, 5, "1M3I4M"});
        tests.add(new Object[]{"2M3I4M", 1, 4, "1M3I3M"});
        tests.add(new Object[]{"2M3I4M", 2, 4, "3I3M"});
        tests.add(new Object[]{"2M3I4M", 2, 3, "3I2M"});
        tests.add(new Object[]{"2M3I4M", 2, 2, "3I1M"});
        tests.add(new Object[]{"2M3I4M", 3, 4, "2M"});
        tests.add(new Object[]{"2M3I4M", 3, 3, "1M"});
        tests.add(new Object[]{"2M3I4M", 4, 4, "1M"});
       
       
        return tests.toArray(new Object[][]{});
    }
@dataprovider(name = "trimcigardata") public object[][] maketrimcigardata() { list<object[]> tests = new arraylist<>(); for ( final cigaroperator op : arrays.aslist(cigaroperator.d, cigaroperator.eq, cigaroperator.x, cigaroperator.m) ) { for ( int mylength = 1; mylength < 6; mylength++ ) { for ( int start = 0; start < mylength - 1; start++ ) { for ( int end = start; end < mylength; end++ ) { final int length = end - start + 1; final list<cigaroperator> padops = arrays.aslist(cigaroperator.d, cigaroperator.m); for ( final cigaroperator padop: padops) { for ( int leftpad = 0; leftpad < 2; leftpad++ ) { for ( int rightpad = 0; rightpad < 2; rightpad++ ) { tests.add(new object[]{ (leftpad > 0 ? leftpad + padop.tostring() : "") + mylength + op.tostring() + (rightpad > 0 ? rightpad + padop.tostring() : ""), start + leftpad, end + leftpad, length + op.tostring()}); } } } } } } } for ( final int leftpad : arrays.aslist(0, 1, 2, 5) ) { for ( final int rightpad : arrays.aslist(0, 1, 2, 5) ) { final int length = leftpad + rightpad; if ( length > 0 ) { for ( final int inssize : arrays.aslist(1, 10) ) { for ( int start = 0; start <= leftpad; start++ ) { for ( int stop = leftpad; stop < length; stop++ ) { final int leftpadremaining = leftpad - start; final int rightpadremaining = stop - leftpad + 1; final string insc = inssize + "i"; tests.add(new object[]{ leftpad + "m" + insc + rightpad + "m", start, stop, (leftpadremaining > 0 ? leftpadremaining + "m" : "") + insc + (rightpadremaining > 0 ? rightpadremaining + "m" : "") }); } } } } } } tests.add(new object[]{"3m2d4m", 0, 8, "3m2d4m"}); tests.add(new object[]{"3m2d4m", 2, 8, "1m2d4m"}); tests.add(new object[]{"3m2d4m", 2, 6, "1m2d2m"}); tests.add(new object[]{"3m2d4m", 3, 6, "2d2m"}); tests.add(new object[]{"3m2d4m", 4, 6, "1d2m"}); tests.add(new object[]{"3m2d4m", 5, 6, "2m"}); tests.add(new object[]{"3m2d4m", 6, 6, "1m"}); tests.add(new object[]{"2m3i4m", 0, 5, "2m3i4m"}); tests.add(new object[]{"2m3i4m", 1, 5, "1m3i4m"}); tests.add(new object[]{"2m3i4m", 1, 4, "1m3i3m"}); tests.add(new object[]{"2m3i4m", 2, 4, "3i3m"}); tests.add(new object[]{"2m3i4m", 2, 3, "3i2m"}); tests.add(new object[]{"2m3i4m", 2, 2, "3i1m"}); tests.add(new object[]{"2m3i4m", 3, 4, "2m"}); tests.add(new object[]{"2m3i4m", 3, 3, "1m"}); tests.add(new object[]{"2m3i4m", 4, 4, "1m"}); return tests.toarray(new object[][]{}); }