diff --git a/src/PythonicAPI.md b/src/PythonicAPI.md
index f372d366ccce6b04748a5af4bdf34580814ba919..5fd21496c19c8bf15ddb7058e17662cc69e0d3ed 100644
--- a/src/PythonicAPI.md
+++ b/src/PythonicAPI.md
@@ -300,6 +300,12 @@ This section includes ?vtkUnstructuredGrid?.
 
 ### Arrays
 
+| Example Name | Description | Image |
+| -------------- | ------------- | ------- |
+[ArrayToTable](/PythonicAPI/InfoVis/ArrayToTable) | Convert a vtkDenseArray to a vtkTable.
+[ArrayWriter](/PythonicAPI/Utilities/ArrayWriter) | Write a DenseArray or SparseArray to a file.
+
+
 ### Events
 
 ## Math Operations
@@ -308,6 +314,7 @@ This section includes ?vtkUnstructuredGrid?.
 
 | Example Name | Description | Image |
 | -------------- | ------------- | ------- |
+[AdjacencyMatrixToEdgeTable](/PythonicAPI/Graphs/AdjacencyMatrixToEdgeTable) | Convert an adjacency matrix to an edge table.
 [ConstructTree](/PythonicAPI/Graphs/ConstructTree) | Construct a tree.
 [CreateTree](/PythonicAPI/Graphs/CreateTree) | Create a tree and label the vertices and edges.
 [GraphToPolyData](/PythonicAPI/Graphs/GraphToPolyData) | Convert a graph to a PolyData.
@@ -477,6 +484,7 @@ See [this tutorial](http://www.vtk.org/Wiki/VTK/Tutorials/3DDataTypes) for a bri
 | Example Name | Description | Image |
 | -------------- | ------------- | ------- |
 [BalloonWidget](/PythonicAPI/Widgets/BalloonWidget) | Uses a vtkBalloonWidget to draw labels when the mouse stays above an actor.
+[BorderWidget](/PythonicAPI/Widgets/BorderWidget) | 2D selection, 2D box.
 [BoxWidget](/PythonicAPI/Widgets/BoxWidget) | This 3D widget defines a region of interest that is represented by an arbitrarily oriented hexahedron with interior face angles of 90 degrees (orthogonal faces). The object creates 7 handles that can be moused on and manipulated.
 [BoxWidget2](/PythonicAPI/Widgets/BoxWidget2) |  This 3D widget defines a region of interest that is represented by an arbitrarily oriented hexahedron with interior face angles of 90 degrees (orthogonal faces). The object creates 7 handles that can be moused on and manipulated. ?vtkBoxWidget2? and ?vtkBoxRepresentation? are used in this example.
 [CompassWidget](/PythonicAPI/Widgets/CompassWidget) | Draws an interactive compass.
diff --git a/src/PythonicAPI/Graphs/AdjacencyMatrixToEdgeTable.py b/src/PythonicAPI/Graphs/AdjacencyMatrixToEdgeTable.py
new file mode 100644
index 0000000000000000000000000000000000000000..8bed799ff51c9e7b09c7cdf646102fe1d9ebab81
--- /dev/null
+++ b/src/PythonicAPI/Graphs/AdjacencyMatrixToEdgeTable.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+
+"""
+The output is:
+
+ 10 20 30
+ 40 50 60
+ 70 80 90
+
++-----------------+------------------+
+|                 | value            |
++-----------------+------------------+
+| 2               | 30               |
+| 1               | 20               |
+| 0               | 10               |
+| 2               | 60               |
+| 1               | 50               |
+| 0               | 40               |
+| 2               | 90               |
+| 1               | 80               |
+| 0               | 70               |
++-----------------+------------------+
+
+The first column is the column index of the item in the 'value' column.
+The row index is given by the number of times we've previously seen the column
+index. For some reason, zeros in the matrix are not reported in the table.
+
+For example, the first row says that the value '30' is in column 2 of the matrix
+(0-based indexing). Since we have not previously seen an item in column 2, it is
+in row 0 of the matrix.
+
+The fourth row says that the value '60' is also in column 2. We infer that '60'
+is row 1 of the matrix because we have already seen one item (the '30') in
+column 2.
+
+"""
+
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkInteractionStyle
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkRenderingOpenGL2
+from vtkmodules.vtkCommonCore import vtkDenseArray
+from vtkmodules.vtkCommonDataModel import vtkArrayData
+from vtkmodules.vtkInfovisCore import (
+    vtkAdjacencyMatrixToEdgeTable,
+    vtkArrayToTable
+)
+
+
+def main():
+    # This is a templated class, note the use of square brackets for the template arguments.
+    array = vtkDenseArray['float']()
+    array.Resize(3, 3)
+
+    counter = 1
+    scale = 10
+    for i in range(0, array.extents[0].GetEnd()):
+        for j in range(0, array.extents[1].GetEnd()):
+            array.SetValue(i, j, counter * scale)
+            counter += 1
+
+    array_data = vtkArrayData()
+    array_data.AddArray(array)
+
+    # Optional step to check what we entered.
+    table = vtkArrayToTable(input_data=array_data)
+    table.update()
+    table.output.Dump()
+
+    adjacency_matrix_to_edge_table = vtkAdjacencyMatrixToEdgeTable(input_data=array_data)
+    adjacency_matrix_to_edge_table.update()
+    adjacency_matrix_to_edge_table.output.Dump()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/PythonicAPI/InfoVis/ArrayToTable.py b/src/PythonicAPI/InfoVis/ArrayToTable.py
new file mode 100644
index 0000000000000000000000000000000000000000..512da3618e623b91f6ca522779473438a85a1704
--- /dev/null
+++ b/src/PythonicAPI/InfoVis/ArrayToTable.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkInteractionStyle
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkRenderingOpenGL2
+from vtkmodules.vtkCommonCore import vtkDenseArray
+from vtkmodules.vtkCommonDataModel import vtkArrayData
+from vtkmodules.vtkInfovisCore import (
+    vtkArrayToTable
+)
+
+
+def main():
+    # This is a templated class, note the use of square brackets for the template arguments.
+    array = vtkDenseArray['int']()
+    array.Resize(2, 4)
+
+    print(f'The extents are are: ({array.extents[0].GetEnd()}, {array.extents[1].GetEnd()})')
+    #     Set the values.
+    for i in range(0, array.extents[0].GetEnd()):
+        for j in range(0, array.extents[1].GetEnd()):
+            array.SetValue(i, j, i + j)
+
+    array_data = vtkArrayData()
+    array_data.AddArray(array)
+
+    table = vtkArrayToTable(input_data=array_data)
+    table.update()
+    table.output.Dump()
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/PythonicAPI/Snippets/VTKDataClasses.md b/src/PythonicAPI/Snippets/VTKDataClasses.md
index e2a33b19576c1339378a1b03b8f87ab60026d455..9752d7f6f94f9499417d574cd908cf95b26f70f3 100644
--- a/src/PythonicAPI/Snippets/VTKDataClasses.md
+++ b/src/PythonicAPI/Snippets/VTKDataClasses.md
@@ -449,6 +449,20 @@ class Mapper:
         VTK_SCALAR_MODE_USE_CELL_FIELD_DATA: int = 4
         VTK_SCALAR_MODE_USE_FIELD_DATA: int = 5
 
+```
+### PlatonicSolidSource
+
+``` Python
+@dataclass(frozen=True)
+class PlatonicSolidSource:
+    @dataclass(frozen=True)
+    class SolidType:
+        VTK_SOLID_TETRAHEDRON: int = 0
+        VTK_SOLID_CUBE: int = 1
+        VTK_SOLID_OCTAHEDRON: int = 2
+        VTK_SOLID_ICOSAHEDRON: int = 3
+        VTK_SOLID_DODECAHEDRON: int = 4
+
 ```
 
 ### Property
diff --git a/src/PythonicAPI/Utilities/ArrayWriter.py b/src/PythonicAPI/Utilities/ArrayWriter.py
new file mode 100644
index 0000000000000000000000000000000000000000..e287a2c6f5fbdb5a1ad41c595991bbae8836613f
--- /dev/null
+++ b/src/PythonicAPI/Utilities/ArrayWriter.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkInteractionStyle
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkRenderingOpenGL2
+from vtkmodules.vtkCommonCore import vtkDenseArray
+from vtkmodules.vtkCommonDataModel import vtkArrayData
+from vtkmodules.vtkIOCore import vtkArrayWriter
+
+
+def main():
+    # This is a templated class, note the use of square brackets for the template arguments.
+    array = vtkDenseArray['float']()
+    array.Resize(1, 3)
+    array.SetValue(0, 0, 1.0)
+    array.SetValue(0, 1, 2.0)
+    array.SetValue(0, 2, 3.0)
+
+    print(f'The extents are are: ({array.extents[0].GetEnd()}, {array.extents[1].GetEnd()})')
+    #     Set the values.
+    for i in range(0, array.extents[0].GetEnd()):
+        for j in range(0, array.extents[1].GetEnd()):
+            array.SetValue(i, j, i + j)
+
+    # Method 1
+    array_data = vtkArrayData()
+    array_data.AddArray(array)
+
+    writer1 = vtkArrayWriter(file_name='Test1.txt', input_data=array_data)
+    writer1.Write()
+
+    # Method 2
+    file_name = 'Test2.txt'
+    writer2 = vtkArrayWriter()
+    writer2.Write(array, file_name)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/PythonicAPI/Widgets/BorderWidget.md b/src/PythonicAPI/Widgets/BorderWidget.md
new file mode 100644
index 0000000000000000000000000000000000000000..9410d4da05b94453ff0668525ac227239dfaa5a8
--- /dev/null
+++ b/src/PythonicAPI/Widgets/BorderWidget.md
@@ -0,0 +1,3 @@
+### Description
+
+This example draws a border around a region selected with the mouse. Note that the default border color is white - so if you have a white background you will not see anything!
diff --git a/src/PythonicAPI/Widgets/BorderWidget.py b/src/PythonicAPI/Widgets/BorderWidget.py
new file mode 100644
index 0000000000000000000000000000000000000000..e14cd4eeb3f5a36133471e97f5b32ef9ed5c31c2
--- /dev/null
+++ b/src/PythonicAPI/Widgets/BorderWidget.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+
+from dataclasses import dataclass
+
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkInteractionStyle
+# noinspection PyUnresolvedReferences
+import vtkmodules.vtkRenderingOpenGL2
+from vtkmodules.vtkCommonColor import vtkNamedColors
+from vtkmodules.vtkCommonCore import (
+    vtkLookupTable
+)
+from vtkmodules.vtkFiltersSources import vtkPlatonicSolidSource
+from vtkmodules.vtkInteractionWidgets import (
+    vtkBorderRepresentation,
+    vtkBorderWidget
+
+)
+from vtkmodules.vtkRenderingCore import (
+    vtkActor,
+    vtkPolyDataMapper,
+    vtkRenderWindow,
+    vtkRenderWindowInteractor,
+    vtkRenderer
+)
+
+
+def main():
+    colors = vtkNamedColors()
+
+    lut = get_platonic_lut()
+
+    # A renderer, render window and interactor.
+    ren = vtkRenderer(background=colors.GetColor3d('SteelBlue'))
+    ren_win = vtkRenderWindow(window_name='BorderWidget')
+    ren_win.AddRenderer(ren)
+    iren = vtkRenderWindowInteractor()
+    iren.render_window = ren_win
+
+    platonic_solid = vtkPlatonicSolidSource(solid_type=PlatonicSolidSource.SolidType.VTK_SOLID_DODECAHEDRON)
+    mapper = vtkPolyDataMapper(lookup_table=lut, scalar_range=(0, 19))
+    platonic_solid >> mapper
+    actor = vtkActor(mapper=mapper)
+    ren.AddActor(actor)
+
+    # Create the widget and its representation
+    rep = vtkBorderRepresentation(proportional_resize=True, show_border=True)
+    # This has no effect, the border remains white.
+    rep.border_property.color = colors.GetColor3d('Yellow')
+
+    widget = vtkBorderWidget(interactor=iren, representation=rep, selectable=False)
+    widget.AddObserver('EndInteractionEvent', BorderCallback(ren))
+
+    ren_win.Render()
+    ren.active_camera.Elevation(30.0)
+    ren.active_camera.Azimuth(180.0)
+
+    iren.Initialize()
+    ren_win.Render()
+    widget.On()
+    iren.Start()
+
+
+def get_platonic_lut():
+    """
+    Get a specialised lookup table for the platonic solids.
+
+    Since each face of a vtkPlatonicSolidSource has a different
+    cell scalar, we create a lookup table with a different colour
+    for each face.
+    The colors have been carefully chosen so that adjacent cells
+    are colored distinctly.
+
+    :return: The lookup table.
+    """
+    lut = vtkLookupTable(number_of_table_values=20, table_range=(0.0, 19.0))
+    # lut.SetNumberOfTableValues(20)
+    # lut.SetTableRange(0.0, 19.0)
+    lut.Build()
+    lut.SetTableValue(0, 0.1, 0.1, 0.1)
+    lut.SetTableValue(1, 0, 0, 1)
+    lut.SetTableValue(2, 0, 1, 0)
+    lut.SetTableValue(3, 0, 1, 1)
+    lut.SetTableValue(4, 1, 0, 0)
+    lut.SetTableValue(5, 1, 0, 1)
+    lut.SetTableValue(6, 1, 1, 0)
+    lut.SetTableValue(7, 0.9, 0.7, 0.9)
+    lut.SetTableValue(8, 0.5, 0.5, 0.5)
+    lut.SetTableValue(9, 0.0, 0.0, 0.7)
+    lut.SetTableValue(10, 0.5, 0.7, 0.5)
+    lut.SetTableValue(11, 0, 0.7, 0.7)
+    lut.SetTableValue(12, 0.7, 0, 0)
+    lut.SetTableValue(13, 0.7, 0, 0.7)
+    lut.SetTableValue(14, 0.7, 0.7, 0)
+    lut.SetTableValue(15, 0, 0, 0.4)
+    lut.SetTableValue(16, 0, 0.4, 0)
+    lut.SetTableValue(17, 0, 0.4, 0.4)
+    lut.SetTableValue(18, 0.4, 0, 0)
+    lut.SetTableValue(19, 0.4, 0, 0.4)
+    return lut
+
+
+class BorderCallback(object):
+    def __init__(self, ren):
+        self.ren = ren
+
+    def __call__(self, caller, ev):
+        # Just do this to demonstrate who called callback and the event that triggered it.
+        # print(caller.GetClassName(), 'Event Id:', ev)
+        rep = caller.representation
+        # Viewport coordinates.
+        lower_left = rep.position
+        upper_right = rep.position2
+        print('Viewport coordinates:')
+        print(f'Lower left:  ({lower_left[0]:5.2f}, {lower_left[1]:5.2f}),')
+        print(f'Upper right: ({lower_left[0] + upper_right[0]:5.2f}, {lower_left[1] + upper_right[1]:5.2f}),')
+        # World coordinates.
+        # lower_left_coordinate = rep.position_coordinate
+        # lower_left = lower_left_coordinate.GetComputedWorldValue(self.ren)
+        # upper_right_coordinate = rep.position2_coordinate
+        # upper_right = upper_right_coordinate.GetComputedWorldValue(self.ren)
+        # print('World coordinates:')
+        # print(f'Lower left:  ({lower_left[0]:5.2f}, {lower_left[1]:5.2f}),')
+        # print(f'Upper right: ({upper_right[0]:5.2f}, {upper_right[1]:5.2f}),')
+
+
+@dataclass(frozen=True)
+class PlatonicSolidSource:
+    @dataclass(frozen=True)
+    class SolidType:
+        VTK_SOLID_TETRAHEDRON: int = 0
+        VTK_SOLID_CUBE: int = 1
+        VTK_SOLID_OCTAHEDRON: int = 2
+        VTK_SOLID_ICOSAHEDRON: int = 3
+        VTK_SOLID_DODECAHEDRON: int = 4
+
+
+if __name__ == '__main__':
+    main()
diff --git a/src/Testing/Baseline/PythonicAPI/Widgets/TestBorderWidget.png b/src/Testing/Baseline/PythonicAPI/Widgets/TestBorderWidget.png
new file mode 100644
index 0000000000000000000000000000000000000000..1785686db4c8b74d1e3c0e26b4e005c9e27eecd4
--- /dev/null
+++ b/src/Testing/Baseline/PythonicAPI/Widgets/TestBorderWidget.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ba65c407c19a373d3796b0ebe950bd71849306a098b57a4295708ab9bfe336dc
+size 4369