docs: @Pure
  	@SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:nestedifdepth"})
  	public int transform(Point1D<?, ?, S> point, Tuple2D<?> appliedTranslation) {
  		assert point != null : AssertMessages.notNullParameter(0);
  		assert point.getSegment() != null;
  
  		int idx;
  		double distanceToSegmentEnd;
  		Direction1D direction;
  		S previousSegment;
  		double shift = point.getY();
  		double curviline = point.getCurvilineCoordinate();
  		S segment = point.getSegment();
  		double distance = 0;
  
  		// Ensure the path is valid
  		final List<S> rpath;
  		if (this.path == null || this.path.isEmpty()) {
  			rpath = Collections.singletonList(segment);
  		} else {
  			rpath = this.path;
  		}
  
  		// Test if the point is located on the the first segment
  		if (!segment.equals(rpath.get(0))) {
  			return -1;
  		}
  
  		// Change the shift.
  		if (this.firstSegmentDirection.isSegmentDirection()) {
  			shift += this.shiftTranslation;
  		} else {
  			shift -= this.shiftTranslation;
  		}
  
  		double distanceToMove = this.curvilineTranslation;
  		if (distanceToMove >= 0.) {
  			// Move foward, along the path.
  			direction = this.firstSegmentDirection;
  			idx = 0;
  			do {
  				if (direction.isSegmentDirection()) {
  					distanceToSegmentEnd = segment.getLength() - curviline;
  					if (distanceToSegmentEnd < distanceToMove) {
  						distance += distanceToSegmentEnd;
  						if ((idx + 1) < rpath.size()) {
  							previousSegment = segment;
  							++idx;
  							segment = rpath.get(idx);
  							distanceToMove -= distanceToSegmentEnd;
  							if (segment.isLastPointConnectedTo(previousSegment) || previousSegment.equals(segment)) {
  								shift = -shift;
  								curviline = segment.getLength();
  								direction = Direction1D.REVERTED_DIRECTION;
  							} else {
  								curviline = 0.;
  							}
  						} else {
  							curviline = segment.getLength();
  							distanceToMove = 0.;
  						}
  					} else {
  						curviline += distanceToMove;
  						distance += distanceToMove;
  						distanceToMove = 0.;
  					}
  				} else {
  					distanceToSegmentEnd = curviline;
  					if (distanceToSegmentEnd < distanceToMove) {
  						distance += distanceToSegmentEnd;
  						if ((idx + 1) < rpath.size()) {
  							++idx;
  							previousSegment = segment;
  							segment = rpath.get(idx);
  							distanceToMove -= distanceToSegmentEnd;
  							if (segment.isFirstPointConnectedTo(previousSegment)
  									|| previousSegment.equals(segment)) {
  								shift = -shift;
  								curviline = 0.;
  								direction = Direction1D.SEGMENT_DIRECTION;
  							} else {
  								curviline = segment.getLength();
  							}
  						} else {
  							distanceToMove = 0.;
  							curviline = 0.;
  						}
  					} else {
  						curviline -= distanceToMove;
  						distance += distanceToMove;
  						distanceToMove = 0.;
  					}
  				}
  			} while (distanceToMove > 0.);
  		} else {
  			// Move backward. This operation can be applied only of
  			// the current segment.
  			idx = 0;
  			if (this.firstSegmentDirection.isSegmentDirection()) {
  				// Caution: distanceToMove is negative
  				distance = Math.min(curviline, -distanceToMove);
  				curviline -= distance;
  				if (curviline < 0.) {
  					curviline = 0.;
  				}
  			} else {
  				// Caution: distanceToMove is negative
  				distance = Math.min(segment.getLength() - curviline, -distanceToMove);
  				curviline += distance;
  				if (curviline > segment.getLength()) {
  					curviline = segment.getLength();
  				}
  			}
  		}
  
  		if (appliedTranslation != null) {
  			appliedTranslation.set(
  					distance,
  					Math.abs(this.shiftTranslation));
  		}
  
  		point.set(segment, curviline, shift);
  
  		return idx;
  	}