/* * Copyright 2010 Henry Coles * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and limitations under the License. */ package org.pitest.mutationtest.engine.gregor.mutators; import java.math.BigInteger; import java.util.Collection; import java.util.concurrent.Callable; import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.IntFunction; import java.util.function.Supplier; import org.junit.Before; import org.junit.Test; import org.pitest.mutationtest.engine.Mutant; import org.pitest.mutationtest.engine.MutationDetails; import org.pitest.mutationtest.engine.gregor.MutatorTestBase; import org.pitest.mutationtest.engine.gregor.mutators.experimental.BigIntegerMutator; public class BigIntegerMutatorTest extends MutatorTestBase { @Before public void setupEngineToMutateOnlyReturnVals() { createTesteeWith(BigIntegerMutator.INSTANCE); } @Test public void add() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Add.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Add(0, 2), mutant, "-2"); } @Test public void subtract() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Subtract.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Subtract(0, 3), mutant, "3"); } @Test public void mutliply() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Multiply.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Multiply(2, 2), mutant, "1"); } @Test public void divide() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Divide.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Divide(2, 2), mutant, "4"); } @Test public void modulo() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Modulo.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Modulo(25, 5), mutant, "125"); } @Test public void abs() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Abs.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Abs(-25, 6), mutant, "25"); assertMutantCallableReturns(new Abs(25, 6), mutant, "-25"); } @Test public void not() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Not.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Not(0b1111), mutant, String.valueOf(-0b1111)); assertMutantCallableReturns(new Not(0b1111), mutant, String.valueOf(-0b1111)); } @Test public void negate() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Negate.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Negate(0xFFFFFF00), mutant, String.valueOf(0x000000FF)); assertMutantCallableReturns(new Negate(0), mutant, String.valueOf(0xFFFFFFFF)); assertMutantCallableReturns(new Negate(0xFF00FF00), mutant, String.valueOf(0x00FF00FF)); } @Test public void min() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Min.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Min(-25, 6), mutant, "6"); assertMutantCallableReturns(new Min(25, 6), mutant, "25"); } @Test public void max() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Max.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Max(-25, 6), mutant, "-25"); assertMutantCallableReturns(new Max(25, 6), mutant, "6"); } @Test public void setBit() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(SetBit.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new SetBit(0b11101, 2), mutant, String.valueOf(0b11001)); assertMutantCallableReturns(new SetBit(0b11001, 2), mutant, String.valueOf(0b11001)); } @Test public void clearBit() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(ClearBit.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new ClearBit(0b11101, 2), mutant, String.valueOf(0b11101)); assertMutantCallableReturns(new ClearBit(0b01101, 0), mutant, String.valueOf(0b01101)); } @Test public void flipBit() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(FlipBit.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new FlipBit(0b11101, 2), mutant, String.valueOf(0b11101)); assertMutantCallableReturns(new FlipBit(0b01101, 0), mutant, String.valueOf(0b01101)); } @Test public void shiftLeft() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(ShiftLeft.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new ShiftLeft(1, 1), mutant, String.valueOf(1 >> 1)); assertMutantCallableReturns(new ShiftLeft(1, 2), mutant, String.valueOf(1 >> 2)); assertMutantCallableReturns(new ShiftLeft(1 << 8, 8), mutant, String.valueOf(1)); assertMutantCallableReturns(new ShiftLeft(1 << 8, 4), mutant, String.valueOf(1 << 8 >> 4)); } @Test public void shiftRight() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(ShiftRight.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new ShiftRight(1, 1), mutant, String.valueOf(1 << 1)); assertMutantCallableReturns(new ShiftRight(1, 2), mutant, String.valueOf(1 << 2)); assertMutantCallableReturns(new ShiftRight(1 << 8, 8), mutant, String.valueOf(1L << 16L)); assertMutantCallableReturns(new ShiftRight(1 << 8, 4), mutant, String.valueOf(1 << 8 << 4)); } @Test public void and() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(And.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new And(0b01, 0b10), mutant, String.valueOf(0b11)); assertMutantCallableReturns(new And(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new And(0b01, 0b00), mutant, String.valueOf(0b01)); } @Test public void or() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Or.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Or(0b01, 0b10), mutant, String.valueOf(0b00)); assertMutantCallableReturns(new Or(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new Or(0b11, 0b10), mutant, String.valueOf(0b10)); } @Test public void xor() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(Xor.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new Xor(0b01, 0b10), mutant, String.valueOf(0b00)); assertMutantCallableReturns(new Xor(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new Xor(0b11, 0b10), mutant, String.valueOf(0b10)); } @Test public void andNot() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(AndNot.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new AndNot(0b01, 0b10), mutant, String.valueOf(0b00)); assertMutantCallableReturns(new AndNot(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new AndNot(0b11, 0b10), mutant, String.valueOf(0b10)); } @Test public void addLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(AddLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new AddLambda(0, 2), mutant, "-2"); } @Test public void subtractLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(SubtractLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new SubtractLambda(0, 3), mutant, "3"); } @Test public void mutliplyLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(MultiplyLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new MultiplyLambda(2, 2), mutant, "1"); } @Test public void divideLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(DivideLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new DivideLambda(2, 2), mutant, "4"); } @Test public void moduloLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(ModuloLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new ModuloLambda(25, 5), mutant, "125"); } @Test public void absLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(AbsLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new AbsLambda(-25, 6), mutant, "25"); assertMutantCallableReturns(new AbsLambda(25, 6), mutant, "-25"); } @Test public void notLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(NotLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new NotLambda(0b1111), mutant, String.valueOf(-0b1111)); assertMutantCallableReturns(new NotLambda(0b1111), mutant, String.valueOf(-0b1111)); } @Test public void negateLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(NegateLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new NegateLambda(0xFFFFFF00), mutant, String.valueOf(0x000000FF)); assertMutantCallableReturns(new NegateLambda(0), mutant, String.valueOf(0xFFFFFFFF)); assertMutantCallableReturns(new NegateLambda(0xFF00FF00), mutant, String.valueOf(0x00FF00FF)); } @Test public void minLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(MinLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new MinLambda(-25, 6), mutant, "6"); assertMutantCallableReturns(new MinLambda(25, 6), mutant, "25"); } @Test public void maxLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(MaxLambda.class); final Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new MaxLambda(-25, 6), mutant, "-25"); assertMutantCallableReturns(new MaxLambda(25, 6), mutant, "6"); } @Test public void setBitLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(SetBitLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new SetBitLambda(0b11101, 2), mutant, String.valueOf(0b11001)); assertMutantCallableReturns(new SetBitLambda(0b11001, 2), mutant, String.valueOf(0b11001)); } @Test public void clearBitLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(ClearBitLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new ClearBitLambda(0b11101, 2), mutant, String.valueOf(0b11101)); assertMutantCallableReturns(new ClearBitLambda(0b01101, 0), mutant, String.valueOf(0b01101)); } @Test public void flipBitLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(FlipBitLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new FlipBitLambda(0b11101, 2), mutant, String.valueOf(0b11101)); assertMutantCallableReturns(new FlipBitLambda(0b01101, 0), mutant, String.valueOf(0b01101)); } @Test public void shiftLeftLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(ShiftLeftLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new ShiftLeftLambda(1, 1), mutant, String.valueOf(1 >> 1)); assertMutantCallableReturns(new ShiftLeftLambda(1, 2), mutant, String.valueOf(1 >> 2)); assertMutantCallableReturns(new ShiftLeftLambda(1 << 8, 8), mutant, String.valueOf(1)); assertMutantCallableReturns(new ShiftLeftLambda(1 << 8, 4), mutant, String.valueOf(1 << 8 >> 4)); } @Test public void shiftRightLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(ShiftRightLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new ShiftRightLambda(1, 1), mutant, String.valueOf(1 << 1)); assertMutantCallableReturns(new ShiftRightLambda(1, 2), mutant, String.valueOf(1 << 2)); assertMutantCallableReturns(new ShiftRightLambda(1 << 8, 8), mutant, String.valueOf(1L << 16L)); assertMutantCallableReturns(new ShiftRightLambda(1 << 8, 4), mutant, String.valueOf(1 << 8 << 4)); } @Test public void andLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(AndLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new AndLambda(0b01, 0b10), mutant, String.valueOf(0b11)); assertMutantCallableReturns(new AndLambda(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new AndLambda(0b01, 0b00), mutant, String.valueOf(0b01)); } @Test public void orLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(OrLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new OrLambda(0b01, 0b10), mutant, String.valueOf(0b00)); assertMutantCallableReturns(new OrLambda(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new OrLambda(0b11, 0b10), mutant, String.valueOf(0b10)); } @Test public void xorLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(XorLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new XorLambda(0b01, 0b10), mutant, String.valueOf(0b00)); assertMutantCallableReturns(new XorLambda(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new XorLambda(0b11, 0b10), mutant, String.valueOf(0b10)); } @Test public void andNotLambda() throws Exception { final Collection<MutationDetails> actual = findMutationsFor(AndNotLambda.class); Mutant mutant = getFirstMutant(actual); assertMutantCallableReturns(new AndNotLambda(0b01, 0b10), mutant, String.valueOf(0b00)); assertMutantCallableReturns(new AndNotLambda(0b01, 0b01), mutant, String.valueOf(0b01)); assertMutantCallableReturns(new AndNotLambda(0b11, 0b10), mutant, String.valueOf(0b10)); } private static abstract class AbstractMath implements Callable<String> { private final BigInteger value1; private final BigInteger value2; AbstractMath(long v1, long v2) { this.value1 = BigInteger.valueOf(v1); this.value2 = BigInteger.valueOf(v2); } abstract BigInteger apply(BigInteger left, BigInteger right); @Override public String call() throws Exception { return String.valueOf(apply(value1, value2)); } } private static class Add extends AbstractMath { Add(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.add(right); } } private static class Subtract extends AbstractMath { Subtract(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.subtract(right); } } private static class Divide extends AbstractMath { Divide(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.divide(right); } } private static class Multiply extends AbstractMath { Multiply(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.multiply(right); } } private static class Modulo extends AbstractMath { Modulo(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.mod(right); } } private static class SetBit extends AbstractMath { SetBit(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.setBit(right.intValue()); } } private static class ClearBit extends AbstractMath { ClearBit(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.clearBit(right.intValue()); } } private static class FlipBit extends AbstractMath { FlipBit(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.flipBit(right.intValue()); } } private static class ShiftLeft extends AbstractMath { ShiftLeft(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.shiftLeft(right.intValue()); } } private static class ShiftRight extends AbstractMath { ShiftRight(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.shiftRight(right.intValue()); } } private static class And extends AbstractMath { And(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.and(right); } } private static class Or extends AbstractMath { Or(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.or(right); } } private static class Xor extends AbstractMath { Xor(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.xor(right); } } private static class AndNot extends AbstractMath { AndNot(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.andNot(right); } } private static class Max extends AbstractMath { Max(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.max(right); } } private static class Min extends AbstractMath { Min(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.min(right); } } private static class Not extends AbstractMath { Not(long v1) { super(v1, 0L); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.not(); } } private static class Negate extends AbstractMath { Negate(long v1) { super(v1, 0L); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.negate(); } } private static class Abs extends AbstractMath { Abs(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { return left.abs(); } } private static class AddLambda extends AbstractMath { AddLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::add; return function.apply(left, right); } } private static class SubtractLambda extends AbstractMath { SubtractLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::subtract; return function.apply(left, right); } } private static class DivideLambda extends AbstractMath { DivideLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::divide; return function.apply(left, right); } } private static class MultiplyLambda extends AbstractMath { MultiplyLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::multiply; return function.apply(left, right); } } private static class SetBitLambda extends AbstractMath { SetBitLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { IntFunction<BigInteger> function = left::setBit; return function.apply(right.intValue()); } } private static class ClearBitLambda extends AbstractMath { ClearBitLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { IntFunction<BigInteger> function = left::clearBit; return function.apply(right.intValue()); } } private static class FlipBitLambda extends AbstractMath { FlipBitLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { IntFunction<BigInteger> function = left::flipBit; return function.apply(right.intValue()); } } private static class ShiftLeftLambda extends AbstractMath { ShiftLeftLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { IntFunction<BigInteger> function = left::shiftLeft; return function.apply(right.intValue()); } } private static class ShiftRightLambda extends AbstractMath { ShiftRightLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { IntFunction<BigInteger> function = left::shiftRight; return function.apply(right.intValue()); } } private static class AndLambda extends AbstractMath { AndLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::and; return function.apply(left, right); } } private static class OrLambda extends AbstractMath { OrLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::or; return function.apply(left, right); } } private static class XorLambda extends AbstractMath { XorLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::xor; return function.apply(left, right); } } private static class AndNotLambda extends AbstractMath { AndNotLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::andNot; return function.apply(left, right); } } private static class MaxLambda extends AbstractMath { MaxLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::max; return function.apply(left, right); } } private static class MinLambda extends AbstractMath { MinLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::min; return function.apply(left, right); } } private static class NotLambda extends AbstractMath { NotLambda(long v1) { super(v1, 0L); } @Override BigInteger apply(BigInteger left, BigInteger right) { Supplier<BigInteger> function = left::not; return function.get(); } } private static class NegateLambda extends AbstractMath { NegateLambda(long v1) { super(v1, 0L); } @Override BigInteger apply(BigInteger left, BigInteger right) { Function<BigInteger, BigInteger> function = BigInteger::negate; return function.apply(left); } } private static class AbsLambda extends AbstractMath { AbsLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { Function<BigInteger, BigInteger> function = BigInteger::abs; return function.apply(left); } } private static class ModuloLambda extends AbstractMath { ModuloLambda(long v1, long v2) { super(v1, v2); } @Override BigInteger apply(BigInteger left, BigInteger right) { BiFunction<BigInteger, BigInteger, BigInteger> function = BigInteger::mod; return function.apply(left, right); } } }