docs: @SuppressWarnings({"checkstyle:cyclomaticcomplexity", "checkstyle:npathcomplexity"})
  	public Set<Integer> removeRoadSegment(RoadSegment segment, boolean tryToReconnect) {
  		final IntegerList removedIndexes = new IntegerList();
  		if (segment != null) {
  			final Map<BusItineraryHalt, RoadSegment> segmentMap = new TreeMap<>(
  					(obj1, obj2) -> Integer.compare(System.identityHashCode(obj1), System.identityHashCode(obj2)));
  
  			// Save the segment-halt binding
  			final Iterator<BusItineraryHalt> haltIterator = this.validHalts.iterator();
  			while (haltIterator.hasNext()) {
  				final BusItineraryHalt halt = haltIterator.next();
  				final int sgmtIndex = halt.getRoadSegmentIndex();
  				final RoadSegment s = this.roadSegments.getRoadSegmentAt(sgmtIndex);
  				if (s.equals(segment)) {
  					segmentMap.put(halt, null);
  				} else {
  					segmentMap.put(halt, s);
  				}
  			}
  
  			// Removed the segments
  			int segmentIndex = 0;
  			final Iterator<RoadSegment> segmentIterator = this.roadSegments.roadSegments();
  			while (segmentIterator.hasNext()) {
  				final RoadSegment s = segmentIterator.next();
  				if (s.equals(segment)) {
  					segmentIterator.remove();
  					removedIndexes.add(Integer.valueOf(segmentIndex));
  				}
  				++segmentIndex;
  			}
  
  			// Try to reconnect the segments
  			if (tryToReconnect) {
  				for (int i = 0; i < this.roadSegments.size() - 1; ++i) {
  					final RoadPath p1 = this.roadSegments.getRoadPathAt(i);
  					int j = i + 1;
  					while (j < this.roadSegments.size()) {
  						final RoadPath p2 = this.roadSegments.getRoadPathAt(j);
  						RoadSegment seg = p2.getConnectableSegmentToFirstPoint(p1);
  						final Iterator<RoadSegment> iterator;
  						if (seg != null) {
  							iterator = p2.iterator();
  						} else {
  							seg = p2.getConnectableSegmentToLastPoint(p1);
  							if (seg != null) {
  								iterator = ListUtil.reverseIterator(p2);
  							} else {
  								iterator = null;
  							}
  						}
  						if (iterator != null) {
  							assert seg != null;
  							assert iterator.hasNext();
  							final RoadSegment sgmt = iterator.next();
  							// avoid to connect paths that cause to go back on the same segment.
  							if (!seg.equals(sgmt)) {
  								p1.add(sgmt);
  								while (iterator.hasNext()) {
  									p1.add(iterator.next());
  								}
  								this.roadSegments.remove(p2);
  							} else {
  								++j;
  							}
  						} else {
  							++j;
  						}
  					}
  				}
  				this.roadSegments.sync();
  			}
  
  			if (!removedIndexes.isEmpty()) {
  				//
  				// Force the road segment indexes
  				//
  				for (final Entry<BusItineraryHalt, RoadSegment> entry : segmentMap.entrySet()) {
  					final BusItineraryHalt halt = entry.getKey();
  					final RoadSegment s = entry.getValue();
  					if (s == null) {
  						halt.setRoadSegmentIndex(-1);
  						halt.setPositionOnSegment(Float.NaN);
  						halt.checkPrimitiveValidity();
  					} else {
  						final int sgmtIndex = halt.getRoadSegmentIndex();
  						final int idx = this.roadSegments.indexOf(s);
  						if (idx != sgmtIndex) {
  							halt.setRoadSegmentIndex(idx);
  							halt.checkPrimitiveValidity();
  						}
  					}
  				}
  
  				//
  				// Change the road network reference
  				//
  				if (this.roadSegments.isEmpty() && this.roadNetwork != null) {
  					final RoadNetwork network = this.roadNetwork.get();
  					if (network != null) {
  						network.removeRoadNetworkListener(this);
  					}
  					this.roadNetwork = null;
  				}
  
  				//
  				// Change the road network reference
  				//
  				for (final Integer index : removedIndexes) {
  					fireShapeChanged(new BusChangeEvent(this,
  							BusChangeEventType.SEGMENT_REMOVED,
  							segment,
  							index.intValue(),
  							"shape", //$NON-NLS-1$
  							null,
  							null));
  				}
  				checkPrimitiveValidity();
  			}
  		}
  		return removedIndexes;
  	}