@NotNull
 public static char[] adaptiveLoadText(@NotNull Reader reader) throws IOException {
   char[] chars = new char[4096];
   List<char[]> buffers = null;
   int count = 0;
   int total = 0;
   while (true) {
     int n = reader.read(chars, count, chars.length - count);
     if (n <= 0) break;
     count += n;
     if (total > 1024 * 1024 * 10) throw new FileTooBigException("File too big " + reader);
     total += n;
     if (count == chars.length) {
       if (buffers == null) {
         buffers = new ArrayList<char[]>();
       }
       buffers.add(chars);
       int newLength = Math.min(1024 * 1024, chars.length * 2);
       chars = new char[newLength];
       count = 0;
     }
   }
   char[] result = new char[total];
   if (buffers != null) {
     for (char[] buffer : buffers) {
       System.arraycopy(buffer, 0, result, result.length - total, buffer.length);
       total -= buffer.length;
     }
   }
   System.arraycopy(chars, 0, result, result.length - total, total);
   return result;
 }
 @NotNull
 public static String loadTextAndClose(@NotNull Reader reader) throws IOException {
   try {
     return StringFactory.createShared(adaptiveLoadText(reader));
   } finally {
     reader.close();
   }
 }