private TerrainTriangulationData TriangulateRoadAdjacentToRiver(
        Hex source,
        HexDirections direction,
        TerrainTriangulationData data,
        HexRiverData riverData,
        Dictionary <HexDirections, bool> roadEdges,
        float hexOuterRadius,
        int wrapSize,
        MapMeshChunkLayer roads,
        FeatureContainer features
        )
    {
//        bool hasRoadThroughEdge = hex.HasRoadThroughEdge(direction);
        bool hasRoadThroughEdge = roadEdges[direction];

//          bool previousHasRiver = hex.HasRiverThroughEdge(
//              direction.Previous()
//          );
        bool previousHasRiver = riverData.HasIncomingRiverInDirection(
            direction.PreviousClockwise()
            );

//        bool nextHasRiver = hex.HasRiverThroughEdge(direction.Next());
        bool nextHasRiver = riverData.HasIncomingRiverInDirection(
            direction.NextClockwise()
            );

        Vector2 interpolators = GetRoadInterpolators(
            source,
            direction,
            roadEdges
            );

        Vector3 roadCenter = data.terrainCenter;

//        if (hex.HasRiverBeginOrEnd) {
        if (riverData.HasRiverStartOrEnd)
        {
            roadCenter +=
                HexagonPoint.GetSolidEdgeMiddle(
//                    hex.RiverBeginOrEndDirection.Opposite(),
                    riverData.RiverStartOrEndDirection.Opposite(),
                    hexOuterRadius
                    ) *
                (1f / 3f);
        }
//        else if(hex.IncomingRiver == hex.OutgoingRiver.Opposite()) {
        else if (
            riverData.HasStraightRiver
            )
        {
            Vector3 corner;

//  If the previous hex has a river, the corner the center will be
//  moved toward is equal to the current direction + 1.
            if (previousHasRiver)
            {
                if (
                    !hasRoadThroughEdge &&
//                    !hex.HasRoadThroughEdge(direction.Next())
                    !roadEdges[direction.NextClockwise()]
                    )
                {
                    return(data);
                }
                corner = HexagonPoint.GetSecondSolidCorner(
                    direction,
                    hexOuterRadius
                    );
            }
// If the previous hex does not have a river, the corner the center will
// be moved toward is the same index as the current direction.
            else
            {
                if (
                    !hasRoadThroughEdge &&
//                    !hex.HasRoadThroughEdge(direction.Previous())
                    !roadEdges[direction.PreviousClockwise()]
                    )
                {
                    return(data);
                }

                corner = HexagonPoint.GetFirstSolidCorner(
                    direction,
                    hexOuterRadius
                    );
            }

/* Using the example of a river flowing from east to west or west to east, for all cases
 * this will result in the river being pushed either directly "up" north away from the
 * river or directly "down" south away from the river.
 */
            roadCenter += corner * 0.5f;

            if (
//                hex.IncomingRiver == direction.Next() &&
                riverData.IncomingRivers[direction.NextClockwise()] &&
//                hex.HasRoadThroughEdge(direction.Next2()) ||
                roadEdges[direction.NextClockwise2()] ||
//                hex.HasRoadThroughEdge(direction.Opposite())
                roadEdges[direction.Opposite()]
                )
            {
                features.AddBridge(
                    roadCenter,
                    data.terrainCenter - corner * 0.5f,
                    hexOuterRadius,
                    wrapSize
                    );
            }

            data.terrainCenter += corner * 0.25f;
        }

// If the river has a zigzag, then the incoming river will be the on the
// edge previous from the outgoing river or the incoming river will be on
// the next edge of the outoing river. In the case of the former, the
// index of the corner whose vector is pointing away from the river is the
// index of the incoming river + 1. Otherwise it is the index of the
// incoming river. In both cases, subtracting the road center by that
// vector times 0.2f is sufficent to push the road center away from the
// river.

//        else if (hex.IncomingRiver == hex.OutgoingRiver.Previous()) {
        else if (riverData.HasPreviousClockwiseCornerRiver)
        {
            roadCenter -= HexagonPoint.GetSecondCorner(
//                hex.IncomingRiver,
                riverData.AnyIncomingRiver,
                hexOuterRadius
                ) * 0.2f;
        }
//        else if (hex.IncomingRiver == hex.OutgoingRiver.Next()) {
        else if (riverData.HasNextClockwiseCornerRiver)
        {
            roadCenter -= HexagonPoint.GetFirstCorner(
//                hex.IncomingRiver,
                riverData.AnyIncomingRiver,
                hexOuterRadius
                ) * 0.2f;
        }

// If there is a river on the previous and next edges, the river has a
// slight bend. Need to pull the road center toward the current hex edge,
// which will shorten the road back away from the river.

        else if (previousHasRiver && nextHasRiver)
        {
            if (!hasRoadThroughEdge)
            {
                return(data);
            }

// Must account for difference in scale between corners and middles by
// using HexMetrics.innerToOuter.

            Vector3 offset =
                HexagonPoint.GetSolidEdgeMiddle(
                    direction,
                    hexOuterRadius
                    ) *
                HexagonConstants.INNER_TO_OUTER_RATIO;

            roadCenter         += offset * 0.7f;
            data.terrainCenter += offset * 0.5f;
        }

// The only remaining case is that the hex lies on the outside of a
// curving river. In this case, there are three edges pointing away from
// the river. The middle edge of these three edges must be obtained.
// Then, the center of the road is pushed toward the middle of this edge.
        else
        {
            HexDirections middle;
            if (previousHasRiver)
            {
//                middle = direction.Next();
                middle = direction.NextClockwise();
            }
            else if (nextHasRiver)
            {
//                middle = direction.Previous();
                middle = direction.PreviousClockwise();
            }
            else
            {
//                middle = direction;
                middle = direction;
            }

// If there is no road through any of the hexes on the outer side of the
// river bend, then the road center need not move and should instead be
// pruned.
            if (
//                !hex.HasRoadThroughEdge(middle) &&
                !roadEdges[middle] &&
//                !hex.HasRoadThroughEdge(middle.Previous()) &&
                !roadEdges[middle.PreviousClockwise()] &&
//                !hex.HasRoadThroughEdge(middle.Next())
                !roadEdges[middle.NextClockwise()]
                )
            {
                return(data);
            }

            Vector3 offset = HexagonPoint.GetSolidEdgeMiddle(
                middle,
                hexOuterRadius
                );

            roadCenter += offset * 0.25f;

            if (
                direction == middle &&
//                hex.HasRoadThroughEdge(direction.Opposite())
                roadEdges[direction.Opposite()]
                )
            {
                features.AddBridge(
                    roadCenter,
                    data.terrainCenter - offset * (
                        HexagonConstants.INNER_TO_OUTER_RATIO * 0.7f
                        ),
                    hexOuterRadius,
                    wrapSize
                    );
            }
        }

        Vector3 middleLeft =
            Vector3.Lerp(
                roadCenter,
                data.centerEdgeVertices.vertex1,
                interpolators.x
                );

        Vector3 middleRight =
            Vector3.Lerp(
                roadCenter,
                data.centerEdgeVertices.vertex5,
                interpolators.y
                );

        TriangulateRoad(
            roadCenter,
            middleLeft,
            middleRight,
            data.centerEdgeVertices,
            hasRoadThroughEdge,
            source.Index,
            hexOuterRadius,
            wrapSize,
            roads
            );

        if (previousHasRiver)
        {
            TriangulateRoadEdge(
                roadCenter,
                data.terrainCenter,
                middleLeft,
                source.Index,
                hexOuterRadius,
                wrapSize,
                roads
                );
        }

        if (nextHasRiver)
        {
            TriangulateRoadEdge(
                roadCenter,
                middleRight,
                data.terrainCenter,
                source.Index,
                hexOuterRadius,
                wrapSize,
                roads
                );
        }

        return(data);
    }