/** Creates a mapping with required properties. */
 public static Mapping create(MappingType mappingType, int sourceCount, int targetCount) {
   switch (mappingType) {
     case BIJECTION:
       assert sourceCount == targetCount;
       return new Permutation(sourceCount);
     case INVERSE_SURJECTION:
       assert sourceCount >= targetCount;
       return new SurjectionWithInverse(sourceCount, targetCount);
     case PARTIAL_SURJECTION:
     case SURJECTION:
       return new Mappings.PartialMapping(sourceCount, targetCount, mappingType);
     case PARTIAL_FUNCTION:
     case FUNCTION:
       return new PartialFunctionImpl(sourceCount, targetCount, mappingType);
     case INVERSE_FUNCTION:
     case INVERSE_PARTIAL_FUNCTION:
       return new InverseMapping(create(mappingType.inverse(), targetCount, sourceCount));
     default:
       throw Util.needToImplement("no known implementation for mapping type " + mappingType);
   }
 }
 public Mapping inverse() {
   return new PartialMapping(targets.clone(), sources.clone(), mappingType.inverse());
 }