         return node.subviews
     }
 
-    public func describe(node: UIView, depth: Int, prefix: String, last: Bool) -> String {
+    public func describe(_ node: UIView, depth: Int, prefix: String, last: Bool) -> String {
         return "[\(node.dynamicType): Frame = \(node.frame)]"
     }
 }

    associatedtype Node

    func children(of node: Node) -> [Node]
    func describe(node: Node, depth: Int, prefix: String, last: Bool) -> String
}

public struct ViewNodeInspector: NodeInspector {

        return HierarchyPrinter.dfsInspect(inspector: self.inspector, node: self.root, depth: 0, prefix: "", last: true)
    }

    public static func dfsInspect(inspector: Inspector, node: Node, depth: Int, prefix: String, last: Bool) -> String {
        let nodeDescription = inspector.describe(node, depth: depth, prefix: prefix, last: last)
        let horizontalLine = depth > 0 ? " \(last ? "└" : "├")─── " : ""
        let result = "\(prefix)\(horizontalLine)\(nodeDescription)"
        let padding = (last ? " " : "│").padding(toLength: depth > 0 ? 6 : 0, withPad: " ", startingAt: 0)
        let newPrefix = "\(prefix) \(padding)"
        let children = inspector.children(of: node)
        let childCount = children.count
        return children.enumerated().reduce(result) { result, obj in
            let index = obj.offset
            let subNode = obj.element
            let subResult = self.dfsInspect(inspector: inspector, node: subNode, depth: depth + 1, prefix: newPrefix, last: index == childCount - 1)
            return "\(result)\n\(subResult)"
