FungibleTransitionMapper { public List<SpunParticle> mapToParticles( List<T> currentParticles, UInt256 totalAmountToTransfer ) throws NotEnoughFungiblesException { final List<SpunParticle> spunParticles = new ArrayList<>(); spunParticles.add(SpunParticle.up( outputCreator.apply(totalAmountToTransfer) )); UInt256 amountLeftToTransfer = totalAmountToTransfer; for (T p : currentParticles) { spunParticles.add(SpunParticle.down(p)); UInt256 particleAmount = inputAmountMapper.apply(p); if (particleAmount.compareTo(amountLeftToTransfer) > 0) { final UInt256 sendBackToSelf = particleAmount.subtract(amountLeftToTransfer); spunParticles.add(SpunParticle.up( inputCreator.apply(sendBackToSelf) )); return spunParticles; } else if (particleAmount.compareTo(amountLeftToTransfer) == 0) { return spunParticles; } amountLeftToTransfer = amountLeftToTransfer.subtract(particleAmount); } throw new NotEnoughFungiblesException(totalAmountToTransfer, totalAmountToTransfer.subtract(amountLeftToTransfer)); } FungibleTransitionMapper(
		Function<T, UInt256> inputAmountMapper,
		Function<UInt256, T> inputCreator,
		Function<UInt256, U> outputCreator
	); List<SpunParticle> mapToParticles(
		List<T> currentParticles,
		UInt256 totalAmountToTransfer
	);  }
@Test public void when_creating_a_transition_from_one_to_one__then_should_be_two_particles() throws NotEnoughFungiblesException { List<SpunParticle> spunParticles = this.mapper.mapToParticles( ImmutableList.of(new TestParticle(UInt256.TWO)), UInt256.TWO ); assertThat(spunParticles).hasSize(2); }
@Test public void when_creating_a_transition_with_not_enough_input__an_exception_should_be_thrown() { assertThatThrownBy(() -> this.mapper.mapToParticles( ImmutableList.of(new TestParticle(UInt256.ONE)), UInt256.TWO) ) .isInstanceOf(NotEnoughFungiblesException.class) .matches(e -> { NotEnoughFungiblesException notEnoughFungiblesException = (NotEnoughFungiblesException) e; return notEnoughFungiblesException.getCurrent().equals(UInt256.ONE) && notEnoughFungiblesException.getRequested().equals(UInt256.TWO); }); }