Refactored using the new root and segments API
diff --git a/okio/src/commonMain/kotlin/okio/internal/-Path.kt b/okio/src/commonMain/kotlin/okio/internal/-Path.kt
index c09967f..0b69590 100644
--- a/okio/src/commonMain/kotlin/okio/internal/-Path.kt
+++ b/okio/src/commonMain/kotlin/okio/internal/-Path.kt
@@ -15,13 +15,13 @@
  */
 package okio.internal
 
-import kotlin.native.concurrent.SharedImmutable
 import okio.Buffer
 import okio.ByteString
 import okio.ByteString.Companion.encodeUtf8
 import okio.ExperimentalFileSystem
 import okio.Path
 import okio.Path.Companion.toPath
+import kotlin.native.concurrent.SharedImmutable
 
 @SharedImmutable
 private val SLASH = "/".encodeUtf8()
@@ -230,49 +230,41 @@
 @ExperimentalFileSystem
 @Suppress("NOTHING_TO_INLINE")
 internal inline fun Path.commonRelativeTo(other: Path): Path {
-  require(isAbsolute && other.isAbsolute || isRelative && other.isRelative) {
+  require(root == other.root) {
     "Paths of different roots cannot be relative to each other: $this and $other"
   }
 
-  val slash = slash ?: other.slash ?: Path.DIRECTORY_SEPARATOR.toSlash()
+  val thisSegments = segmentsBytes
+  val otherSegments = other.segmentsBytes
 
   // We look at the path both have in common.
-  var lastCommonByteIndex = 0
-  val minSize = minOf(bytes.size, other.bytes.size)
-  while (lastCommonByteIndex < minSize &&
-    bytes[lastCommonByteIndex].equalsEitherSlash(other.bytes[lastCommonByteIndex])
+  var firstNewSegmentIndex = 0
+  val minSegmentsSize = minOf(thisSegments.size, otherSegments.size)
+  while (firstNewSegmentIndex < minSegmentsSize &&
+    thisSegments[firstNewSegmentIndex] == otherSegments[firstNewSegmentIndex]
   ) {
-    lastCommonByteIndex++
+    firstNewSegmentIndex++
   }
 
-  if (lastCommonByteIndex == minSize && bytes.size == other.bytes.size) {
+  if (firstNewSegmentIndex == minSegmentsSize && bytes.size == other.bytes.size) {
     // `this` and `other` are the same path.
     return ".".toPath()
   }
 
-  require(lastCommonByteIndex > 0 || !isAbsolute) {
-    "Paths of different roots cannot be relative to each other: $this and $other"
-  }
-
-  val lastCommonSlashIndex = bytes.lastIndexOf(slash, lastCommonByteIndex)
-  require(other.bytes.indexOf(DOT_DOT, lastCommonSlashIndex) == -1) {
+  require(otherSegments.subList(firstNewSegmentIndex, otherSegments.size).indexOf(DOT_DOT) == -1) {
     "Impossible relative path to resolve: $this and $other"
   }
 
-  val firstDiffIndex = lastCommonSlashIndex + slash.size
-
   val buffer = Buffer()
-  val stepsToCommonParent =
-    other.bytes.substring(firstDiffIndex, other.bytes.size).count(other.slash ?: slash)
-  // We check if there is a trailing path segment on `other`.
-  if (other.bytes.size > firstDiffIndex) {
-    for (j in 0..stepsToCommonParent) {
-      buffer.write(DOT_DOT)
-      buffer.write(other.slash ?: slash)
-    }
+  val slash = other.slash ?: slash ?: Path.DIRECTORY_SEPARATOR.toSlash()
+  for (i in firstNewSegmentIndex until otherSegments.size) {
+    buffer.write(DOT_DOT)
+    buffer.write(slash)
   }
-
-  buffer.write(bytes.substring(firstDiffIndex, bytes.size))
+  for (i in firstNewSegmentIndex until thisSegments.size) {
+    buffer.write(thisSegments[i])
+    buffer.write(slash)
+  }
   return buffer.toPath()
 }
 
diff --git a/okio/src/commonTest/kotlin/okio/PathTest.kt b/okio/src/commonTest/kotlin/okio/PathTest.kt
index 9761c37..ec71d21 100644
--- a/okio/src/commonTest/kotlin/okio/PathTest.kt
+++ b/okio/src/commonTest/kotlin/okio/PathTest.kt
@@ -537,8 +537,8 @@
   fun relativeToRelativeWithMiddleDotsInCommonPrefix() {
     val a = "Desktop/documents/a...n/red".toPath()
     val b = "Desktop/documents/a...m/blue".toPath()
-    assertRelativeTo(a, b, "../a...m/blue".toPath())
-    assertRelativeTo(b, a, "../a...n/red".toPath())
+    assertRelativeTo(a, b, "../../a...m/blue".toPath())
+    assertRelativeTo(b, a, "../../a...n/red".toPath())
   }
 
   @Test