class FileSizeFormat {
    public enum ScaleUnit {
        BYTE {
            @Override
            public long bytes() {
                return 1L;
            }

            @Override
            public String symbol() {
                return "B";
            }
        },
        KILOBYTE {
            @Override
            public long bytes() {
                return 1000L;
            }

            @Override
            public String symbol() {
                return "kB";
            }
        },
        MEGABYTE {
            @Override
            public long bytes() {
                return KILOBYTE.bytes() * KILOBYTE.bytes();
            }

            @Override
            public String symbol() {
                return "MB";
            }
        },
        GIGABYTE {
            @Override
            public long bytes() {
                return MEGABYTE.bytes() * KILOBYTE.bytes();
            }
            ;

            @Override
            public String symbol() {
                return "GB";
            }
        };

        public abstract long bytes();

        public abstract String symbol();

        public static ScaleUnit getScaleUnit(long size) {<FILL_FUNCTION_BODY>}
    }

    public FileSizeFormat(Locale locale) {}

    public String format(long size) {
        return format(size, null);
    }

    public String format(long size, ScaleUnit unit) {
        return format(size, unit, false);
    }

    public String format(long size, ScaleUnit unit, boolean omitSymbol) {
        StringBuilder sb = new StringBuilder();
        format(sb, size, unit, omitSymbol);
        return sb.toString();
    }

    public void format(StringBuilder builder, long size) {
        format(builder, size, null, false);
    }

    public void format(StringBuilder builder, long size, ScaleUnit unit) {
        format(builder, size, unit, false);
    }

    @SuppressWarnings("checkstyle:magicnumber")
    private void format(StringBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) {
        if (size < 0L) {
            throw new IllegalArgumentException("file size cannot be negative: " + size);
        }
        if (unit == null) {
            unit = ScaleUnit.getScaleUnit(size);
        }

        double scaledSize = (double) size / unit.bytes();

        if (unit == ScaleUnit.BYTE) {
            builder.append(size);
        } else if (scaledSize < 0.05d || scaledSize >= 10.0d) {
            builder.append(Math.round(scaledSize));
        } else {
            builder.append(Math.round(scaledSize * 10d) / 10d);
        }

        if (!omitSymbol) {
            builder.append(" ").append(unit.symbol());
        }
    }

    public void format(MessageBuilder builder, long size) {
        format(builder, size, null, false);
    }

    public void format(MessageBuilder builder, long size, ScaleUnit unit) {
        format(builder, size, unit, false);
    }

    @SuppressWarnings("checkstyle:magicnumber")
    private void format(MessageBuilder builder, long size, ScaleUnit unit, boolean omitSymbol) {
        if (size < 0L) {
            throw new IllegalArgumentException("file size cannot be negative: " + size);
        }
        if (unit == null) {
            unit = ScaleUnit.getScaleUnit(size);
        }

        double scaledSize = (double) size / unit.bytes();

        if (unit == ScaleUnit.BYTE) {
            builder.append(Long.toString(size));
        } else if (scaledSize < 0.05d || scaledSize >= 10.0d) {
            builder.append(Long.toString(Math.round(scaledSize)));
        } else {
            builder.append(Double.toString(Math.round(scaledSize * 10d) / 10d));
        }

        if (!omitSymbol) {
            builder.append(" ").append(unit.symbol());
        }
    }

    public String formatProgress(long progressedSize, long size) {
        StringBuilder sb = new StringBuilder();
        formatProgress(sb, progressedSize, size);
        return sb.toString();
    }

    public void formatProgress(StringBuilder builder, long progressedSize, long size) {
        if (progressedSize < 0L) {
            throw new IllegalArgumentException("progressed file size cannot be negative: " + size);
        }
        if (size >= 0 && progressedSize > size) {
            throw new IllegalArgumentException(
                    "progressed file size cannot be greater than size: " + progressedSize + " > " + size);
        }

        if (size >= 0L && progressedSize != size) {
            ScaleUnit unit = ScaleUnit.getScaleUnit(size);
            format(builder, progressedSize, unit, true);
            builder.append("/");
            format(builder, size, unit, false);
        } else {
            ScaleUnit unit = ScaleUnit.getScaleUnit(progressedSize);

            format(builder, progressedSize, unit, false);
        }
    }
}

            if (size < 0L) {
                throw new IllegalArgumentException("file size cannot be negative: " + size);
            }

            if (size >= GIGABYTE.bytes()) {
                return GIGABYTE;
            } else if (size >= MEGABYTE.bytes()) {
                return MEGABYTE;
            } else if (size >= KILOBYTE.bytes()) {
                return KILOBYTE;
            } else {
                return BYTE;
            }
        
<no_super_class>