+
+def boundary_fill(
+    dest_bitmap: Bitmap,
+    x: int,
+    y: int,
+    fill_color_value: int,
+    replaced_color_value: Optional[int] = None,
+):
+    """Draws the color value into the destination bitmap enclosed
+    area of pixels of the background_value color. Like "Paint Bucket"
+    fill tool.
+
+    :param bitmap dest_bitmap: Destination bitmap that will be written into
+    :param int x: x-pixel position of the first pixel to check and fill if needed
+    :param int y: y-pixel position of the first pixel to check and fill if needed
+    :param int fill_color_value: Bitmap palette index that will be written into the
+           enclosed area in the destination bitmap
+    :param int replaced_color_value: Bitmap palette index that will filled with the
+           value color in the enclosed area in the destination bitmap"""
+    if fill_color_value == replaced_color_value:
+        return
+    if replaced_color_value == -1:
+        replaced_color_value = dest_bitmap[x, y]
+
+    fill_points = []
+    fill_points.append((x, y))
+
+    seen_points = []
+    minx = x
+    miny = y
+    maxx = x
+    maxy = y
+
+    while len(fill_points) > 0:
+        cur_point = fill_points.pop(0)
+        seen_points.append(cur_point)
+        cur_x = cur_point[0]
+        cur_y = cur_point[1]
+
+        cur_point_color = dest_bitmap[cur_x, cur_y]
+        if replaced_color_value is not None and cur_point_color != replaced_color_value:
+            continue
+        if cur_x < minx:
+            minx = cur_x
+        if cur_y < miny:
+            miny = cur_y
+        if cur_x > maxx:
+            maxx = cur_x
+        if cur_y > maxy:
+            maxy = cur_y
+
+        dest_bitmap[cur_x, cur_y] = fill_color_value
+
+        above_point = (cur_x, cur_y - 1)
+        below_point = (cur_x, cur_y + 1)
+        left_point = (cur_x - 1, cur_y)
+        right_point = (cur_x + 1, cur_y)
+
+        if (
+            above_point[1] >= 0
+            and above_point not in seen_points
+            and above_point not in fill_points
+        ):
+            fill_points.append(above_point)
+        if (
+            below_point[1] < dest_bitmap.height
+            and below_point not in seen_points
+            and below_point not in fill_points
+        ):
+            fill_points.append(below_point)
+        if (
+            left_point[0] >= 0
+            and left_point not in seen_points
+            and left_point not in fill_points
+        ):
+            fill_points.append(left_point)
+        if (
+            right_point[0] < dest_bitmap.width
+            and right_point not in seen_points
+            and right_point not in fill_points
+        ):
+            fill_points.append(right_point)