code: import java.io.ByteArrayOutputStream;
  import java.nio.charset.StandardCharsets;
  import java.util.Arrays;
  
  public class MutableByteString {
  
      private byte[] bytes;
      private int length;
  
      public MutableByteString(byte... bytes) {
          setInternal(bytes);
      }
  
      public int length() {
          return length;
      }
  
      public boolean isEmpty() {
          return length == 0;
      }
  
      public byte get(int index) {
          return bytes[check(index)];
      }
  
      public void set(byte[] bytes) {
          setInternal(bytes);
      }
  
      public void set(int index, byte b) {
          bytes[check(index)] = b;
      }
  
      public void append(byte b) {
          if (length >= bytes.length) {
              int len = 2 * bytes.length;
              if (len < 0)
                  len = Integer.MAX_VALUE;
              bytes = Arrays.copyOf(bytes, len);
          }
          bytes[length] = b;
          length++;
      }
  
      public MutableByteString substring(int from, int to) {
          return new MutableByteString(Arrays.copyOfRange(bytes, from, to));
      }
  
      public void replace(byte[] from, byte[] to) {
          ByteArrayOutputStream copy = new ByteArrayOutputStream();
          if (from.length == 0) {
              for (byte b : bytes) {
                  copy.write(to, 0, to.length);
                  copy.write(b);
              }
              copy.write(to, 0, to.length);
          } else {
              for (int i = 0; i < length; i++) {
                  if (regionEquals(i, from)) {
                      copy.write(to, 0, to.length);
                      i += from.length - 1;
                  } else {
                      copy.write(bytes[i]);
                  }
              }
          }
          set(copy.toByteArray());
      }
  
      public boolean regionEquals(int offset, MutableByteString other, int otherOffset, int len) {
          if (Math.max(offset, otherOffset) + len < 0)
              return false;
          if (offset + len > length || otherOffset + len > other.length())
              return false;
          for (int i = 0; i < len; i++) {
              if (bytes[offset + i] != other.get(otherOffset + i))
                  return false;
          }
          return true;
      }
  
      public String toHexString() {
          char[] hex = new char[2 * length];
          for (int i = 0; i < length; i++) {
              hex[2 * i] = "0123456789abcdef".charAt(bytes[i] >> 4 & 0x0F);
              hex[2 * i + 1] = "0123456789abcdef".charAt(bytes[i] & 0x0F);
          }
          return new String(hex);
      }
  
      public String toStringUtf8() {
          return new String(bytes, 0, length, StandardCharsets.UTF_8);
      }
  
      private void setInternal(byte[] bytes) {
          this.bytes = bytes.clone();
          this.length = bytes.length;
      }
  
      private boolean regionEquals(int offset, byte[] other) {
          int len = other.length;
          if (offset < 0 || offset + len < 0)
              return false;
          if (offset + len > length)
              return false;
          for (int i = 0; i < len; i++) {
              if (bytes[offset + i] != other[i])
                  return false;
          }
          return true;
      }
  
      private int check(int index) {
          if (index < 0 || index >= length)
              throw new IndexOutOfBoundsException(String.valueOf(index));
          return index;
      }
  }
  