   }
 
   public func traverse(_ stmt: DeferStatement) throws -> Bool {
-    return try visit(stmt)
+    guard try visit(stmt) else { return false }
+    return try traverse(stmt.codeBlock)
   }
 
   public func traverse(_ stmt: DoStatement) throws -> Bool {
-    return try visit(stmt)
+    guard try visit(stmt) else { return false }
+
+    guard try traverse(stmt.codeBlock) else { return false }
+    for catchBlock in stmt.catchClauses {
+      if let expr = catchBlock.whereExpression {
+        guard try traverse(expr) else { return false }
+      }
+      guard try traverse(catchBlock.codeBlock) else { return false }
+    }
+
+    return true
   }
 
   public func traverse(_ stmt: FallthroughStatement) throws -> Bool {

  }

  public func traverse(_ stmt: ForInStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: GuardStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: IfStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: LabeledStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: RepeatWhileStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: ReturnStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: SwitchStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: ThrowStatement) throws -> Bool {
    return try visit(stmt)
  }

  public func traverse(_ stmt: WhileStatement) throws -> Bool {
    return try visit(stmt)
  }

  // Expressions

    }
  }

  private func traverse(_ statements: Statements) throws -> Bool {
    for stmt in statements {
      guard try traverse(stmt) else { return false }
    }
    return true
  }

  public func traverse(_ stmt: BreakStatement) throws -> Bool {
    return try visit(stmt)
  }
