Link { public static RoadSegment addJoin(RoadSegment sourceRoad, RoadSegment sinkRoad) { final int limit = Math.min(sourceRoad.trafficLaneMax(), sinkRoad.trafficLaneMax()); for (int lane = 1; lane <= limit; ++lane) { addLanePair(lane, sourceRoad, lane, sinkRoad); } return sinkRoad; } private  Link(); static void addLanePair(int fromLane, RoadSegment fromRoadsegment, int toLane, RoadSegment toRoadSegment); static RoadSegment addJoin(RoadSegment sourceRoad, RoadSegment sinkRoad); static void addMerge(RoadSegment fromRoad1, RoadSegment fromRoad2, RoadSegment toRoad); static void addFork(RoadSegment fromRoad, RoadSegment toRoad1, RoadSegment toRoad2);  }
@Test public final void testAddOffsetJoin() { final int laneCount = 2; final int offset = 1; final RoadMapping m1 = new RoadMappingConcrete(laneCount, 1000.0); final RoadSegment r1 = new RoadSegment(m1); final RoadMapping m2 = new RoadMappingConcrete(laneCount + offset, 1000.0); final RoadSegment r2 = new RoadSegment(m2); r2.setLaneType(Lanes.LANE3, Lanes.Type.ENTRANCE); final RoadMapping m3 = new RoadMappingConcrete(laneCount, 1000.0); final RoadSegment r3 = new RoadSegment(m3); Link.addJoin(r1, r2); assertEquals(r2, r1.sinkRoadSegment(Lanes.LANE1)); assertEquals(r2, r1.sinkRoadSegment(Lanes.LANE2)); assertEquals(Lanes.LANE1, r1.sinkLane(Lanes.LANE1)); assertEquals(Lanes.LANE2, r1.sinkLane(Lanes.LANE2)); assertEquals(r1, r2.sourceRoadSegment(Lanes.LANE1)); assertEquals(r1, r2.sourceRoadSegment(Lanes.LANE2)); assertEquals(Lanes.LANE1, r2.sourceLane(Lanes.LANE1)); assertEquals(Lanes.LANE2, r2.sourceLane(Lanes.LANE2)); Link.addJoin(r2, r3); assertEquals(r3, r2.sinkRoadSegment(Lanes.LANE1)); assertEquals(r3, r2.sinkRoadSegment(Lanes.LANE2)); assertEquals(Lanes.LANE1, r2.sinkLane(Lanes.LANE1)); assertEquals(Lanes.LANE2, r2.sinkLane(Lanes.LANE2)); assertEquals(r2, r3.sourceRoadSegment(Lanes.LANE1)); assertEquals(r2, r3.sourceRoadSegment(Lanes.LANE2)); assertEquals(Lanes.LANE1, r3.sourceLane(Lanes.LANE1)); assertEquals(Lanes.LANE2, r3.sourceLane(Lanes.LANE2)); }