We seem to be doing a lot of conversions between `parts` and `String`. If the canonical representation is a list of `parts`, shouldn't all operations be done on `parts`, without converting back and forth to `String`? I see that at least `startsWith` and `append` do that.

Another observation is that `RouteUri` is an immutable class, so we could keep both representations if needed, instead of re-computing the string each time we need it. But ideally, we'd converge to only one representation that supports all operations.