 
     /// Convenience initializer that verifies that the path is absolute.
     public init(validating path: String) throws {
-#if os(Windows)
-        let fsr: UnsafePointer<Int8> = path.fileSystemRepresentation
-        defer { fsr.deallocate() }
-
-        let realpath = String(cString: fsr)
-        if realpath.withCString(encodedAs: UTF16.self, PathIsRelativeW) {
-            throw PathValidationError.invalidAbsolutePath(path)
-        }
-        self.init(path)
-#else
-        switch path.first {
-        case "/":
-            self.init(path)
-        case "~":
-            throw PathValidationError.startsWithTilde(path)
-        default:
-            throw PathValidationError.invalidAbsolutePath(path)
-        }
-#endif
+        try self.init(PathImpl(validatingAbsolutePath: path))
     }
 
     /// Directory component.  An absolute path always has a non-empty directory

    /// and `RelativePath`; particular file systems may have their own
    /// additional requirements.
    static func isValidComponent(_ name: String) -> Bool {
        return name != "" && name != "." && name != ".." && !name.contains("/")
    }

    /// Private implementation details, shared with the RelativePath struct.

    }
}

/// Private implementation shared between AbsolutePath and RelativePath.
protocol Path: Hashable {

    /// Root directory.
    static var root: Self { get }

    /// Checks if a string is a valid component.
    static func isValidComponent(_ name: String) -> Bool

    /// Normalized string of the (absolute or relative) path. Never empty.
    var string: String { get }

    /// Returns whether the path is an absolute path.
    var isAbsolute: Bool { get }

    /// Returns the directory part of the stored path (relying on the fact that it has been normalized). Returns a
    /// string consisting of just `.` if there is no directory part (which is the case if and only if there is no path
    /// separator).
    var dirname: String { get }

    /// Returns the last past component.
    var basename: String { get }

    /// Returns the components of the path between each path separator.
    var components: [String] { get }

    /// Path of parent directory. This always returns a path, because every directory has a parent (the parent
    /// directory of the root directory is considered to be the root directory itself).
    var parentDirectory: Self { get }

    /// Creates a path from its normalized string representation.
    init(string: String)

    /// Creates a path from an absolute string representation and normalizes it.
    init(normalizingAbsolutePath: String)

    /// Creates a path from an relative string representation and normalizes it.
    init(normalizingRelativePath: String)

    /// Creates a path from a string representation, validates that it is a valid absolute path and normalizes it.
    init(validatingAbsolutePath: String) throws

    /// Creates a path from a string representation, validates that it is a valid relative path and normalizes it.
    init(validatingRelativePath: String) throws

    /// Returns suffix with leading `.` if withDot is true otherwise without it.
    func suffix(withDot: Bool) -> String?

    /// Returns a new Path by appending the path component.
    func appending(component: String) -> Self

    /// Returns a path by concatenating a relative path and renormalizing if necessary.
    func appending(relativePath: Self) -> Self
}

extension Path {
    var suffix: String? {
        return suffix(withDot: true)
    }

    var `extension`: String? {
        return suffix(withDot: false)
    }
}

private struct UNIXPath: Path {
    let string: String

    static let root = UNIXPath(string: "/")

    static func isValidComponent(_ name: String) -> Bool {
        return name != "" && name != "." && name != ".." && !name.contains("/")
    }

    var dirname: String {
#if os(Windows)
        let dir = string.deletingLastPathComponent
        return dir == "" ? "." : dir
