// 
// Decompiled by Procyon v0.6.0
// 

package it.unimi.dsi.fastutil.io;

import java.util.NoSuchElementException;
import it.unimi.dsi.fastutil.doubles.DoubleIterable;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import it.unimi.dsi.fastutil.doubles.DoubleBigArrays;
import java.nio.DoubleBuffer;
import it.unimi.dsi.fastutil.doubles.DoubleMappedBigList;
import it.unimi.dsi.fastutil.longs.LongIterable;
import it.unimi.dsi.fastutil.longs.LongIterator;
import it.unimi.dsi.fastutil.longs.LongBigArrays;
import java.nio.LongBuffer;
import it.unimi.dsi.fastutil.longs.LongMappedBigList;
import it.unimi.dsi.fastutil.floats.FloatIterable;
import it.unimi.dsi.fastutil.floats.FloatIterator;
import it.unimi.dsi.fastutil.floats.FloatBigArrays;
import java.nio.FloatBuffer;
import it.unimi.dsi.fastutil.floats.FloatMappedBigList;
import it.unimi.dsi.fastutil.ints.IntIterable;
import it.unimi.dsi.fastutil.ints.IntIterator;
import it.unimi.dsi.fastutil.ints.IntBigArrays;
import java.nio.IntBuffer;
import it.unimi.dsi.fastutil.ints.IntMappedBigList;
import it.unimi.dsi.fastutil.shorts.ShortIterable;
import it.unimi.dsi.fastutil.shorts.ShortIterator;
import it.unimi.dsi.fastutil.shorts.ShortBigArrays;
import java.nio.ShortBuffer;
import it.unimi.dsi.fastutil.shorts.ShortMappedBigList;
import it.unimi.dsi.fastutil.chars.CharIterable;
import it.unimi.dsi.fastutil.chars.CharIterator;
import it.unimi.dsi.fastutil.chars.CharBigArrays;
import java.nio.CharBuffer;
import it.unimi.dsi.fastutil.chars.CharMappedBigList;
import java.nio.ByteOrder;
import it.unimi.dsi.fastutil.bytes.ByteIterable;
import it.unimi.dsi.fastutil.bytes.ByteIterator;
import it.unimi.dsi.fastutil.bytes.ByteBigArrays;
import java.nio.file.StandardOpenOption;
import java.nio.channels.FileChannel;
import java.nio.file.OpenOption;
import java.nio.channels.WritableByteChannel;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import it.unimi.dsi.fastutil.booleans.BooleanIterable;
import it.unimi.dsi.fastutil.booleans.BooleanIterator;
import it.unimi.dsi.fastutil.booleans.BooleanBigArrays;
import it.unimi.dsi.fastutil.BigArrays;
import java.io.DataOutputStream;
import java.io.DataOutput;
import java.io.DataInputStream;
import java.io.EOFException;
import it.unimi.dsi.fastutil.Arrays;
import java.io.DataInput;
import java.io.ObjectInputStream;
import java.io.InputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.File;

public class BinIO
{
    public static int BUFFER_SIZE;
    private static final int MAX_IO_LENGTH = 1048576;
    
    private BinIO() {
    }
    
    public static void storeObject(final Object o, final File file) throws IOException {
        final ObjectOutputStream oos = new ObjectOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
        oos.writeObject(o);
        oos.close();
    }
    
    public static void storeObject(final Object o, final CharSequence filename) throws IOException {
        storeObject(o, new File(filename.toString()));
    }
    
    public static Object loadObject(final File file) throws IOException, ClassNotFoundException {
        final ObjectInputStream ois = new ObjectInputStream(new FastBufferedInputStream(new FileInputStream(file)));
        final Object result = ois.readObject();
        ois.close();
        return result;
    }
    
    public static Object loadObject(final CharSequence filename) throws IOException, ClassNotFoundException {
        return loadObject(new File(filename.toString()));
    }
    
    public static void storeObject(final Object o, final OutputStream s) throws IOException {
        final ObjectOutputStream oos = new ObjectOutputStream(new FastBufferedOutputStream(s));
        oos.writeObject(o);
        oos.flush();
    }
    
    public static Object loadObject(final InputStream s) throws IOException, ClassNotFoundException {
        final ObjectInputStream ois = new ObjectInputStream(new FastBufferedInputStream(s));
        final Object result = ois.readObject();
        return result;
    }
    
    public static int loadBooleans(final DataInput dataInput, final boolean[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readBoolean();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadBooleans(final DataInput dataInput, final boolean[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readBoolean();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadBooleans(final File file, final boolean[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(new FileInputStream(file)));
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dis.readBoolean();
            }
        }
        catch (final EOFException ex) {}
        dis.close();
        return i;
    }
    
    public static int loadBooleans(final CharSequence filename, final boolean[] array, final int offset, final int length) throws IOException {
        return loadBooleans(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadBooleans(final File file, final boolean[] array) throws IOException {
        return loadBooleans(file, array, 0, array.length);
    }
    
    public static int loadBooleans(final CharSequence filename, final boolean[] array) throws IOException {
        return loadBooleans(new File(filename.toString()), array);
    }
    
    public static boolean[] loadBooleans(final File file) throws IOException {
        final FileInputStream fis = new FileInputStream(file);
        final long length = fis.getChannel().size();
        if (length > 2147483647L) {
            fis.close();
            throw new IllegalArgumentException("File too long: " + fis.getChannel().size() + " bytes (" + length + " elements)");
        }
        final boolean[] array = new boolean[(int)length];
        final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
        for (int i = 0; i < length; ++i) {
            array[i] = dis.readBoolean();
        }
        dis.close();
        return array;
    }
    
    public static boolean[] loadBooleans(final CharSequence filename) throws IOException {
        return loadBooleans(new File(filename.toString()));
    }
    
    public static void storeBooleans(final boolean[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        for (int i = 0; i < length; ++i) {
            dataOutput.writeBoolean(array[offset + i]);
        }
    }
    
    public static void storeBooleans(final boolean[] array, final DataOutput dataOutput) throws IOException {
        for (int length = array.length, i = 0; i < length; ++i) {
            dataOutput.writeBoolean(array[i]);
        }
    }
    
    public static void storeBooleans(final boolean[] array, final int offset, final int length, final File file) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
        for (int i = 0; i < length; ++i) {
            dos.writeBoolean(array[offset + i]);
        }
        dos.close();
    }
    
    public static void storeBooleans(final boolean[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeBooleans(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeBooleans(final boolean[] array, final File file) throws IOException {
        storeBooleans(array, 0, array.length, file);
    }
    
    public static void storeBooleans(final boolean[] array, final CharSequence filename) throws IOException {
        storeBooleans(array, new File(filename.toString()));
    }
    
    public static long loadBooleans(final DataInput dataInput, final boolean[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final boolean[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readBoolean();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadBooleans(final DataInput dataInput, final boolean[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final boolean[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readBoolean();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadBooleans(final File file, final boolean[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        final FileInputStream fis = new FileInputStream(file);
        final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final boolean[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dis.readBoolean();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        dis.close();
        return c;
    }
    
    public static long loadBooleans(final CharSequence filename, final boolean[][] array, final long offset, final long length) throws IOException {
        return loadBooleans(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadBooleans(final File file, final boolean[][] array) throws IOException {
        final FileInputStream fis = new FileInputStream(file);
        final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final boolean[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dis.readBoolean();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        dis.close();
        return c;
    }
    
    public static long loadBooleans(final CharSequence filename, final boolean[][] array) throws IOException {
        return loadBooleans(new File(filename.toString()), array);
    }
    
    public static boolean[][] loadBooleansBig(final File file) throws IOException {
        final FileInputStream fis = new FileInputStream(file);
        final long length = fis.getChannel().size();
        final boolean[][] array = BooleanBigArrays.newBigArray(length);
        final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
        for (int i = 0; i < array.length; ++i) {
            final boolean[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                t[d] = dis.readBoolean();
            }
        }
        dis.close();
        return array;
    }
    
    public static boolean[][] loadBooleansBig(final CharSequence filename) throws IOException {
        return loadBooleansBig(new File(filename.toString()));
    }
    
    public static void storeBooleans(final boolean[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final boolean[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dataOutput.writeBoolean(t[d]);
            }
        }
    }
    
    public static void storeBooleans(final boolean[][] array, final DataOutput dataOutput) throws IOException {
        for (int i = 0; i < array.length; ++i) {
            final boolean[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dataOutput.writeBoolean(t[d]);
            }
        }
    }
    
    public static void storeBooleans(final boolean[][] array, final long offset, final long length, final File file) throws IOException {
        final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final boolean[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dos.writeBoolean(t[d]);
            }
        }
        dos.close();
    }
    
    public static void storeBooleans(final boolean[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeBooleans(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeBooleans(final boolean[][] array, final File file) throws IOException {
        final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
        for (int i = 0; i < array.length; ++i) {
            final boolean[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dos.writeBoolean(t[d]);
            }
        }
        dos.close();
    }
    
    public static void storeBooleans(final boolean[][] array, final CharSequence filename) throws IOException {
        storeBooleans(array, new File(filename.toString()));
    }
    
    public static void storeBooleans(final BooleanIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeBoolean(i.nextBoolean());
        }
    }
    
    public static void storeBooleans(final BooleanIterator i, final File file) throws IOException {
        final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
        while (i.hasNext()) {
            dos.writeBoolean(i.nextBoolean());
        }
        dos.close();
    }
    
    public static void storeBooleans(final BooleanIterator i, final CharSequence filename) throws IOException {
        storeBooleans(i, new File(filename.toString()));
    }
    
    public static BooleanIterator asBooleanIterator(final DataInput dataInput) {
        return new BooleanDataInputWrapper(dataInput);
    }
    
    public static BooleanIterator asBooleanIterator(final File file) throws IOException {
        return new BooleanDataInputWrapper(new DataInputStream(new FastBufferedInputStream(new FileInputStream(file))));
    }
    
    public static BooleanIterator asBooleanIterator(final CharSequence filename) throws IOException {
        return asBooleanIterator(new File(filename.toString()));
    }
    
    public static BooleanIterable asBooleanIterable(final File file) {
        return () -> {
            try {
                return asBooleanIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static BooleanIterable asBooleanIterable(final CharSequence filename) {
        return () -> {
            try {
                return asBooleanIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    private static int read(final InputStream is, final byte[] a, final int offset, final int length) throws IOException {
        if (length == 0) {
            return 0;
        }
        int read = 0;
        do {
            final int result = is.read(a, offset + read, Math.min(length - read, 1048576));
            if (result < 0) {
                return read;
            }
            read += result;
        } while (read < length);
        return read;
    }
    
    private static void write(final OutputStream outputStream, final byte[] a, final int offset, final int length) throws IOException {
        for (int written = 0; written < length; written += Math.min(length - written, 1048576)) {
            outputStream.write(a, offset + written, Math.min(length - written, 1048576));
        }
    }
    
    private static void write(final DataOutput dataOutput, final byte[] a, final int offset, final int length) throws IOException {
        for (int written = 0; written < length; written += Math.min(length - written, 1048576)) {
            dataOutput.write(a, offset + written, Math.min(length - written, 1048576));
        }
    }
    
    public static int loadBytes(final InputStream inputStream, final byte[] array, final int offset, final int length) throws IOException {
        return read(inputStream, array, offset, length);
    }
    
    public static int loadBytes(final InputStream inputStream, final byte[] array) throws IOException {
        return read(inputStream, array, 0, array.length);
    }
    
    public static void storeBytes(final byte[] array, final int offset, final int length, final OutputStream outputStream) throws IOException {
        write(outputStream, array, offset, length);
    }
    
    public static void storeBytes(final byte[] array, final OutputStream outputStream) throws IOException {
        write(outputStream, array, 0, array.length);
    }
    
    private static long read(final InputStream is, final byte[][] a, final long offset, final long length) throws IOException {
        if (length == 0L) {
            return 0L;
        }
        long read = 0L;
        int segment = BigArrays.segment(offset);
        int displacement = BigArrays.displacement(offset);
        do {
            final int result = is.read(a[segment], displacement, (int)Math.min(a[segment].length - displacement, Math.min(length - read, 1048576L)));
            if (result < 0) {
                return read;
            }
            read += result;
            displacement += result;
            if (displacement != a[segment].length) {
                continue;
            }
            ++segment;
            displacement = 0;
        } while (read < length);
        return read;
    }
    
    private static void write(final OutputStream outputStream, final byte[][] a, final long offset, final long length) throws IOException {
        if (length == 0L) {
            return;
        }
        long written = 0L;
        int segment = BigArrays.segment(offset);
        int displacement = BigArrays.displacement(offset);
        do {
            final int toWrite = (int)Math.min(a[segment].length - displacement, Math.min(length - written, 1048576L));
            outputStream.write(a[segment], displacement, toWrite);
            written += toWrite;
            displacement += toWrite;
            if (displacement == a[segment].length) {
                ++segment;
                displacement = 0;
            }
        } while (written < length);
    }
    
    private static void write(final DataOutput dataOutput, final byte[][] a, final long offset, final long length) throws IOException {
        if (length == 0L) {
            return;
        }
        long written = 0L;
        int segment = BigArrays.segment(offset);
        int displacement = BigArrays.displacement(offset);
        do {
            final int toWrite = (int)Math.min(a[segment].length - displacement, Math.min(length - written, 1048576L));
            dataOutput.write(a[segment], displacement, toWrite);
            written += toWrite;
            displacement += toWrite;
            if (displacement == a[segment].length) {
                ++segment;
                displacement = 0;
            }
        } while (written < length);
    }
    
    public static long loadBytes(final InputStream inputStream, final byte[][] array, final long offset, final long length) throws IOException {
        return read(inputStream, array, offset, length);
    }
    
    public static long loadBytes(final InputStream inputStream, final byte[][] array) throws IOException {
        return read(inputStream, array, 0L, BigArrays.length(array));
    }
    
    public static void storeBytes(final byte[][] array, final long offset, final long length, final OutputStream outputStream) throws IOException {
        write(outputStream, array, offset, length);
    }
    
    public static void storeBytes(final byte[][] array, final OutputStream outputStream) throws IOException {
        write(outputStream, array, 0L, BigArrays.length(array));
    }
    
    public static int loadBytes(final ReadableByteChannel channel, final byte[] array, int offset, int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer buffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE);
        int read = 0;
        while (true) {
            buffer.clear();
            buffer.limit();
            final int r = channel.read(buffer);
            if (r <= 0) {
                break;
            }
            read += r;
            buffer.flip();
            buffer.get(array, offset, r);
            offset += r;
            length -= r;
        }
        return read;
    }
    
    public static int loadBytes(final ReadableByteChannel channel, final byte[] array) throws IOException {
        return loadBytes(channel, array, 0, array.length);
    }
    
    public static void storeBytes(final byte[] array, int offset, int length, final WritableByteChannel channel) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer buffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE);
        while (length != 0) {
            final int l = Math.min(length, buffer.capacity());
            buffer.clear();
            buffer.put(array, offset, l);
            buffer.flip();
            channel.write(buffer);
            offset += l;
            length -= l;
        }
    }
    
    public static void storeBytes(final byte[] array, final WritableByteChannel channel) throws IOException {
        storeBytes(array, 0, array.length, channel);
    }
    
    public static long loadBytes(final ReadableByteChannel channel, final byte[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long read = 0L;
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final byte[] t = array[i];
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int e = (int)Math.min(t.length, offset + length - BigArrays.start(i));
            final int r = loadBytes(channel, t, s, e - s);
            read += r;
            if (r < e - s) {
                break;
            }
        }
        return read;
    }
    
    public static long loadBytes(final ReadableByteChannel channel, final byte[][] array) throws IOException {
        return loadBytes(channel, array, 0L, BigArrays.length(array));
    }
    
    public static void storeBytes(final byte[][] array, final long offset, final long length, final WritableByteChannel channel) throws IOException {
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int l = (int)Math.min(array[i].length, offset + length - BigArrays.start(i));
            storeBytes(array[i], s, l - s, channel);
        }
    }
    
    public static void storeBytes(final byte[][] array, final WritableByteChannel channel) throws IOException {
        for (final byte[] t : array) {
            storeBytes(t, channel);
        }
    }
    
    public static int loadBytes(final DataInput dataInput, final byte[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readByte();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadBytes(final DataInput dataInput, final byte[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readByte();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadBytes(final File file, final byte[] array, final int offset, final int length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final int result = loadBytes(channel, array, offset, length);
        channel.close();
        return result;
    }
    
    public static int loadBytes(final CharSequence filename, final byte[] array, final int offset, final int length) throws IOException {
        return loadBytes(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadBytes(final File file, final byte[] array) throws IOException {
        return loadBytes(file, array, 0, array.length);
    }
    
    public static int loadBytes(final CharSequence filename, final byte[] array) throws IOException {
        return loadBytes(new File(filename.toString()), array);
    }
    
    public static byte[] loadBytes(final File file) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size();
        if (length > 2147483647L) {
            channel.close();
            throw new IllegalArgumentException("File too long: " + channel.size() + " bytes (" + length + " elements)");
        }
        final byte[] array = new byte[(int)length];
        if (loadBytes(channel, array) < length) {
            throw new EOFException();
        }
        return array;
    }
    
    public static byte[] loadBytes(final CharSequence filename) throws IOException {
        return loadBytes(new File(filename.toString()));
    }
    
    public static void storeBytes(final byte[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        write(dataOutput, array, offset, length);
    }
    
    public static void storeBytes(final byte[] array, final DataOutput dataOutput) throws IOException {
        write(dataOutput, array, 0, array.length);
    }
    
    public static void storeBytes(final byte[] array, final int offset, final int length, final File file) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeBytes(array, offset, length, channel);
        channel.close();
    }
    
    public static void storeBytes(final byte[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeBytes(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeBytes(final byte[] array, final File file) throws IOException {
        storeBytes(array, 0, array.length, file);
    }
    
    public static void storeBytes(final byte[] array, final CharSequence filename) throws IOException {
        storeBytes(array, new File(filename.toString()));
    }
    
    public static long loadBytes(final DataInput dataInput, final byte[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final byte[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readByte();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadBytes(final DataInput dataInput, final byte[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final byte[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readByte();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadBytes(final File file, final byte[][] array, final long offset, final long length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadBytes(channel, array, offset, length);
        return read;
    }
    
    public static long loadBytes(final CharSequence filename, final byte[][] array, final long offset, final long length) throws IOException {
        return loadBytes(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadBytes(final File file, final byte[][] array) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadBytes(channel, array);
        return read;
    }
    
    public static long loadBytes(final CharSequence filename, final byte[][] array) throws IOException {
        return loadBytes(new File(filename.toString()), array);
    }
    
    public static byte[][] loadBytesBig(final File file) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size();
        final byte[][] array = ByteBigArrays.newBigArray(length);
        loadBytes(channel, array);
        channel.close();
        return array;
    }
    
    public static byte[][] loadBytesBig(final CharSequence filename) throws IOException {
        return loadBytesBig(new File(filename.toString()));
    }
    
    public static void storeBytes(final byte[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        write(dataOutput, array, offset, length);
    }
    
    public static void storeBytes(final byte[][] array, final DataOutput dataOutput) throws IOException {
        write(dataOutput, array, 0L, BigArrays.length(array));
    }
    
    public static void storeBytes(final byte[][] array, final long offset, final long length, final File file) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeBytes(array, offset, length, channel);
        channel.close();
    }
    
    public static void storeBytes(final byte[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeBytes(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeBytes(final byte[][] array, final File file) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeBytes(array, channel);
        channel.close();
    }
    
    public static void storeBytes(final byte[][] array, final CharSequence filename) throws IOException {
        storeBytes(array, new File(filename.toString()));
    }
    
    public static void storeBytes(final ByteIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeByte(i.nextByte());
        }
    }
    
    public static void storeBytes(final ByteIterator i, final File file) throws IOException {
        final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
        while (i.hasNext()) {
            dos.writeByte(i.nextByte());
        }
        dos.close();
    }
    
    public static void storeBytes(final ByteIterator i, final CharSequence filename) throws IOException {
        storeBytes(i, new File(filename.toString()));
    }
    
    public static ByteIterator asByteIterator(final DataInput dataInput) {
        return new ByteDataInputWrapper(dataInput);
    }
    
    public static ByteIterator asByteIterator(final File file) throws IOException {
        return new ByteDataInputWrapper(new DataInputStream(new FastBufferedInputStream(new FileInputStream(file))));
    }
    
    public static ByteIterator asByteIterator(final CharSequence filename) throws IOException {
        return asByteIterator(new File(filename.toString()));
    }
    
    public static ByteIterable asByteIterable(final File file) {
        return () -> {
            try {
                return asByteIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static ByteIterable asByteIterable(final CharSequence filename) {
        return () -> {
            try {
                return asByteIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadChars(final ReadableByteChannel channel, final ByteOrder byteOrder, final char[] array, int offset, int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final CharBuffer buffer = byteBuffer.asCharBuffer();
        int read = 0;
        while (true) {
            byteBuffer.clear();
            byteBuffer.limit();
            int r = channel.read(byteBuffer);
            if (r <= 0) {
                break;
            }
            r >>>= CharMappedBigList.LOG2_BYTES;
            read += r;
            buffer.clear();
            buffer.limit();
            buffer.get(array, offset, r);
            offset += r;
            length -= r;
        }
        return read;
    }
    
    public static int loadChars(final ReadableByteChannel channel, final ByteOrder byteOrder, final char[] array) throws IOException {
        return loadChars(channel, byteOrder, array, 0, array.length);
    }
    
    public static int loadChars(final File file, final ByteOrder byteOrder, final char[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final int read = loadChars(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static int loadChars(final CharSequence filename, final ByteOrder byteOrder, final char[] array, final int offset, final int length) throws IOException {
        return loadChars(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static int loadChars(final File file, final ByteOrder byteOrder, final char[] array) throws IOException {
        return loadChars(file, byteOrder, array, 0, array.length);
    }
    
    public static int loadChars(final CharSequence filename, final ByteOrder byteOrder, final char[] array) throws IOException {
        return loadChars(new File(filename.toString()), byteOrder, array);
    }
    
    public static char[] loadChars(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 2L;
        if (length > 2147483647L) {
            channel.close();
            throw new IllegalArgumentException("File too long: " + channel.size() + " bytes (" + length + " elements)");
        }
        final char[] array = new char[(int)length];
        if (loadChars(channel, byteOrder, array) < length) {
            throw new EOFException();
        }
        channel.close();
        return array;
    }
    
    public static char[] loadChars(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadChars(new File(filename.toString()), byteOrder);
    }
    
    public static void storeChars(final char[] array, int offset, int length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final CharBuffer buffer = byteBuffer.asCharBuffer();
        while (length != 0) {
            final int l = Math.min(length, buffer.capacity());
            buffer.clear();
            buffer.put(array, offset, l);
            buffer.flip();
            byteBuffer.clear();
            byteBuffer.limit();
            channel.write(byteBuffer);
            offset += l;
            length -= l;
        }
    }
    
    public static void storeChars(final char[] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        storeChars(array, 0, array.length, channel, byteOrder);
    }
    
    public static void storeChars(final char[] array, final int offset, final int length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeChars(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeChars(final char[] array, final int offset, final int length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeChars(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeChars(final char[] array, final File file, final ByteOrder byteOrder) throws IOException {
        storeChars(array, 0, array.length, file, byteOrder);
    }
    
    public static void storeChars(final char[] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeChars(array, new File(filename.toString()), byteOrder);
    }
    
    public static long loadChars(final ReadableByteChannel channel, final ByteOrder byteOrder, final char[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long read = 0L;
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final char[] t = array[i];
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int e = (int)Math.min(t.length, offset + length - BigArrays.start(i));
            final int r = loadChars(channel, byteOrder, t, s, e - s);
            read += r;
            if (r < e - s) {
                break;
            }
        }
        return read;
    }
    
    public static long loadChars(final ReadableByteChannel channel, final ByteOrder byteOrder, final char[][] array) throws IOException {
        return loadChars(channel, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadChars(final File file, final ByteOrder byteOrder, final char[][] array, final long offset, final long length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadChars(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static long loadChars(final CharSequence filename, final ByteOrder byteOrder, final char[][] array, final long offset, final long length) throws IOException {
        return loadChars(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static long loadChars(final File file, final ByteOrder byteOrder, final char[][] array) throws IOException {
        return loadChars(file, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadChars(final CharSequence filename, final ByteOrder byteOrder, final char[][] array) throws IOException {
        return loadChars(new File(filename.toString()), byteOrder, array);
    }
    
    public static char[][] loadCharsBig(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 2L;
        final char[][] bigArray;
        final char[][] array = bigArray = CharBigArrays.newBigArray(length);
        for (final char[] t : bigArray) {
            loadChars(channel, byteOrder, t);
        }
        channel.close();
        return array;
    }
    
    public static char[][] loadCharsBig(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadCharsBig(new File(filename.toString()), byteOrder);
    }
    
    public static void storeChars(final char[][] array, final long offset, final long length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int l = (int)Math.min(array[i].length, offset + length - BigArrays.start(i));
            storeChars(array[i], s, l - s, channel, byteOrder);
        }
    }
    
    public static void storeChars(final char[][] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (final char[] t : array) {
            storeChars(t, channel, byteOrder);
        }
    }
    
    public static void storeChars(final char[][] array, final long offset, final long length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeChars(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeChars(final char[][] array, final long offset, final long length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeChars(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeChars(final char[][] array, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeChars(array, channel, byteOrder);
        channel.close();
    }
    
    public static void storeChars(final char[][] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeChars(array, new File(filename.toString()), byteOrder);
    }
    
    public static void storeChars(final CharIterator i, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final CharBuffer buffer = byteBuffer.asCharBuffer();
        while (i.hasNext()) {
            if (!buffer.hasRemaining()) {
                buffer.flip();
                byteBuffer.clear();
                byteBuffer.limit();
                channel.write(byteBuffer);
                buffer.clear();
            }
            buffer.put(i.nextChar());
        }
        buffer.flip();
        byteBuffer.clear();
        byteBuffer.limit();
        channel.write(byteBuffer);
    }
    
    public static void storeChars(final CharIterator i, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeChars(i, channel, byteOrder);
        channel.close();
    }
    
    public static void storeChars(final CharIterator i, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeChars(i, new File(filename.toString()), byteOrder);
    }
    
    public static CharIterator asCharIterator(final ReadableByteChannel channel, final ByteOrder byteOrder) {
        return new CharDataNioInputWrapper(channel, byteOrder);
    }
    
    public static CharIterator asCharIterator(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        return new CharDataNioInputWrapper(channel, byteOrder);
    }
    
    public static CharIterator asCharIterator(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return asCharIterator(new File(filename.toString()), byteOrder);
    }
    
    public static CharIterable asCharIterable(final File file, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asCharIterator(file, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static CharIterable asCharIterable(final CharSequence filename, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asCharIterator(filename, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadChars(final DataInput dataInput, final char[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readChar();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadChars(final DataInput dataInput, final char[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readChar();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadChars(final File file, final char[] array, final int offset, final int length) throws IOException {
        return loadChars(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static int loadChars(final CharSequence filename, final char[] array, final int offset, final int length) throws IOException {
        return loadChars(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadChars(final File file, final char[] array) throws IOException {
        return loadChars(file, array, 0, array.length);
    }
    
    public static int loadChars(final CharSequence filename, final char[] array) throws IOException {
        return loadChars(new File(filename.toString()), array);
    }
    
    public static char[] loadChars(final File file) throws IOException {
        return loadChars(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static char[] loadChars(final CharSequence filename) throws IOException {
        return loadChars(new File(filename.toString()));
    }
    
    public static void storeChars(final char[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        for (int i = 0; i < length; ++i) {
            dataOutput.writeChar(array[offset + i]);
        }
    }
    
    public static void storeChars(final char[] array, final DataOutput dataOutput) throws IOException {
        for (int length = array.length, i = 0; i < length; ++i) {
            dataOutput.writeChar(array[i]);
        }
    }
    
    public static void storeChars(final char[] array, final int offset, final int length, final File file) throws IOException {
        storeChars(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeChars(final char[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeChars(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeChars(final char[] array, final File file) throws IOException {
        storeChars(array, 0, array.length, file);
    }
    
    public static void storeChars(final char[] array, final CharSequence filename) throws IOException {
        storeChars(array, new File(filename.toString()));
    }
    
    public static long loadChars(final DataInput dataInput, final char[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final char[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readChar();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadChars(final DataInput dataInput, final char[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final char[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readChar();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadChars(final File file, final char[][] array, final long offset, final long length) throws IOException {
        return loadChars(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static long loadChars(final CharSequence filename, final char[][] array, final long offset, final long length) throws IOException {
        return loadChars(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadChars(final File file, final char[][] array) throws IOException {
        return loadChars(file, ByteOrder.BIG_ENDIAN, array);
    }
    
    public static long loadChars(final CharSequence filename, final char[][] array) throws IOException {
        return loadChars(new File(filename.toString()), array);
    }
    
    public static char[][] loadCharsBig(final File file) throws IOException {
        return loadCharsBig(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static char[][] loadCharsBig(final CharSequence filename) throws IOException {
        return loadCharsBig(new File(filename.toString()));
    }
    
    public static void storeChars(final char[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final char[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dataOutput.writeChar(t[d]);
            }
        }
    }
    
    public static void storeChars(final char[][] array, final DataOutput dataOutput) throws IOException {
        for (int i = 0; i < array.length; ++i) {
            final char[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dataOutput.writeChar(t[d]);
            }
        }
    }
    
    public static void storeChars(final char[][] array, final long offset, final long length, final File file) throws IOException {
        storeChars(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeChars(final char[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeChars(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeChars(final char[][] array, final File file) throws IOException {
        storeChars(array, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeChars(final char[][] array, final CharSequence filename) throws IOException {
        storeChars(array, new File(filename.toString()));
    }
    
    public static void storeChars(final CharIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeChar(i.nextChar());
        }
    }
    
    public static void storeChars(final CharIterator i, final File file) throws IOException {
        storeChars(i, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeChars(final CharIterator i, final CharSequence filename) throws IOException {
        storeChars(i, new File(filename.toString()));
    }
    
    public static CharIterator asCharIterator(final DataInput dataInput) {
        return new CharDataInputWrapper(dataInput);
    }
    
    public static CharIterator asCharIterator(final File file) throws IOException {
        return asCharIterator(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static CharIterator asCharIterator(final CharSequence filename) throws IOException {
        return asCharIterator(new File(filename.toString()));
    }
    
    public static CharIterable asCharIterable(final File file) {
        return () -> {
            try {
                return asCharIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static CharIterable asCharIterable(final CharSequence filename) {
        return () -> {
            try {
                return asCharIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadShorts(final ReadableByteChannel channel, final ByteOrder byteOrder, final short[] array, int offset, int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final ShortBuffer buffer = byteBuffer.asShortBuffer();
        int read = 0;
        while (true) {
            byteBuffer.clear();
            byteBuffer.limit();
            int r = channel.read(byteBuffer);
            if (r <= 0) {
                break;
            }
            r >>>= ShortMappedBigList.LOG2_BYTES;
            read += r;
            buffer.clear();
            buffer.limit();
            buffer.get(array, offset, r);
            offset += r;
            length -= r;
        }
        return read;
    }
    
    public static int loadShorts(final ReadableByteChannel channel, final ByteOrder byteOrder, final short[] array) throws IOException {
        return loadShorts(channel, byteOrder, array, 0, array.length);
    }
    
    public static int loadShorts(final File file, final ByteOrder byteOrder, final short[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final int read = loadShorts(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static int loadShorts(final CharSequence filename, final ByteOrder byteOrder, final short[] array, final int offset, final int length) throws IOException {
        return loadShorts(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static int loadShorts(final File file, final ByteOrder byteOrder, final short[] array) throws IOException {
        return loadShorts(file, byteOrder, array, 0, array.length);
    }
    
    public static int loadShorts(final CharSequence filename, final ByteOrder byteOrder, final short[] array) throws IOException {
        return loadShorts(new File(filename.toString()), byteOrder, array);
    }
    
    public static short[] loadShorts(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 2L;
        if (length > 2147483647L) {
            channel.close();
            throw new IllegalArgumentException("File too long: " + channel.size() + " bytes (" + length + " elements)");
        }
        final short[] array = new short[(int)length];
        if (loadShorts(channel, byteOrder, array) < length) {
            throw new EOFException();
        }
        channel.close();
        return array;
    }
    
    public static short[] loadShorts(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadShorts(new File(filename.toString()), byteOrder);
    }
    
    public static void storeShorts(final short[] array, int offset, int length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final ShortBuffer buffer = byteBuffer.asShortBuffer();
        while (length != 0) {
            final int l = Math.min(length, buffer.capacity());
            buffer.clear();
            buffer.put(array, offset, l);
            buffer.flip();
            byteBuffer.clear();
            byteBuffer.limit();
            channel.write(byteBuffer);
            offset += l;
            length -= l;
        }
    }
    
    public static void storeShorts(final short[] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        storeShorts(array, 0, array.length, channel, byteOrder);
    }
    
    public static void storeShorts(final short[] array, final int offset, final int length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeShorts(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeShorts(final short[] array, final int offset, final int length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeShorts(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeShorts(final short[] array, final File file, final ByteOrder byteOrder) throws IOException {
        storeShorts(array, 0, array.length, file, byteOrder);
    }
    
    public static void storeShorts(final short[] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeShorts(array, new File(filename.toString()), byteOrder);
    }
    
    public static long loadShorts(final ReadableByteChannel channel, final ByteOrder byteOrder, final short[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long read = 0L;
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final short[] t = array[i];
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int e = (int)Math.min(t.length, offset + length - BigArrays.start(i));
            final int r = loadShorts(channel, byteOrder, t, s, e - s);
            read += r;
            if (r < e - s) {
                break;
            }
        }
        return read;
    }
    
    public static long loadShorts(final ReadableByteChannel channel, final ByteOrder byteOrder, final short[][] array) throws IOException {
        return loadShorts(channel, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadShorts(final File file, final ByteOrder byteOrder, final short[][] array, final long offset, final long length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadShorts(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static long loadShorts(final CharSequence filename, final ByteOrder byteOrder, final short[][] array, final long offset, final long length) throws IOException {
        return loadShorts(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static long loadShorts(final File file, final ByteOrder byteOrder, final short[][] array) throws IOException {
        return loadShorts(file, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadShorts(final CharSequence filename, final ByteOrder byteOrder, final short[][] array) throws IOException {
        return loadShorts(new File(filename.toString()), byteOrder, array);
    }
    
    public static short[][] loadShortsBig(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 2L;
        final short[][] bigArray;
        final short[][] array = bigArray = ShortBigArrays.newBigArray(length);
        for (final short[] t : bigArray) {
            loadShorts(channel, byteOrder, t);
        }
        channel.close();
        return array;
    }
    
    public static short[][] loadShortsBig(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadShortsBig(new File(filename.toString()), byteOrder);
    }
    
    public static void storeShorts(final short[][] array, final long offset, final long length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int l = (int)Math.min(array[i].length, offset + length - BigArrays.start(i));
            storeShorts(array[i], s, l - s, channel, byteOrder);
        }
    }
    
    public static void storeShorts(final short[][] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (final short[] t : array) {
            storeShorts(t, channel, byteOrder);
        }
    }
    
    public static void storeShorts(final short[][] array, final long offset, final long length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeShorts(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeShorts(final short[][] array, final long offset, final long length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeShorts(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeShorts(final short[][] array, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeShorts(array, channel, byteOrder);
        channel.close();
    }
    
    public static void storeShorts(final short[][] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeShorts(array, new File(filename.toString()), byteOrder);
    }
    
    public static void storeShorts(final ShortIterator i, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final ShortBuffer buffer = byteBuffer.asShortBuffer();
        while (i.hasNext()) {
            if (!buffer.hasRemaining()) {
                buffer.flip();
                byteBuffer.clear();
                byteBuffer.limit();
                channel.write(byteBuffer);
                buffer.clear();
            }
            buffer.put(i.nextShort());
        }
        buffer.flip();
        byteBuffer.clear();
        byteBuffer.limit();
        channel.write(byteBuffer);
    }
    
    public static void storeShorts(final ShortIterator i, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeShorts(i, channel, byteOrder);
        channel.close();
    }
    
    public static void storeShorts(final ShortIterator i, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeShorts(i, new File(filename.toString()), byteOrder);
    }
    
    public static ShortIterator asShortIterator(final ReadableByteChannel channel, final ByteOrder byteOrder) {
        return new ShortDataNioInputWrapper(channel, byteOrder);
    }
    
    public static ShortIterator asShortIterator(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        return new ShortDataNioInputWrapper(channel, byteOrder);
    }
    
    public static ShortIterator asShortIterator(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return asShortIterator(new File(filename.toString()), byteOrder);
    }
    
    public static ShortIterable asShortIterable(final File file, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asShortIterator(file, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static ShortIterable asShortIterable(final CharSequence filename, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asShortIterator(filename, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadShorts(final DataInput dataInput, final short[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readShort();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadShorts(final DataInput dataInput, final short[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readShort();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadShorts(final File file, final short[] array, final int offset, final int length) throws IOException {
        return loadShorts(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static int loadShorts(final CharSequence filename, final short[] array, final int offset, final int length) throws IOException {
        return loadShorts(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadShorts(final File file, final short[] array) throws IOException {
        return loadShorts(file, array, 0, array.length);
    }
    
    public static int loadShorts(final CharSequence filename, final short[] array) throws IOException {
        return loadShorts(new File(filename.toString()), array);
    }
    
    public static short[] loadShorts(final File file) throws IOException {
        return loadShorts(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static short[] loadShorts(final CharSequence filename) throws IOException {
        return loadShorts(new File(filename.toString()));
    }
    
    public static void storeShorts(final short[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        for (int i = 0; i < length; ++i) {
            dataOutput.writeShort(array[offset + i]);
        }
    }
    
    public static void storeShorts(final short[] array, final DataOutput dataOutput) throws IOException {
        for (int length = array.length, i = 0; i < length; ++i) {
            dataOutput.writeShort(array[i]);
        }
    }
    
    public static void storeShorts(final short[] array, final int offset, final int length, final File file) throws IOException {
        storeShorts(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeShorts(final short[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeShorts(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeShorts(final short[] array, final File file) throws IOException {
        storeShorts(array, 0, array.length, file);
    }
    
    public static void storeShorts(final short[] array, final CharSequence filename) throws IOException {
        storeShorts(array, new File(filename.toString()));
    }
    
    public static long loadShorts(final DataInput dataInput, final short[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final short[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readShort();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadShorts(final DataInput dataInput, final short[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final short[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readShort();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadShorts(final File file, final short[][] array, final long offset, final long length) throws IOException {
        return loadShorts(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static long loadShorts(final CharSequence filename, final short[][] array, final long offset, final long length) throws IOException {
        return loadShorts(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadShorts(final File file, final short[][] array) throws IOException {
        return loadShorts(file, ByteOrder.BIG_ENDIAN, array);
    }
    
    public static long loadShorts(final CharSequence filename, final short[][] array) throws IOException {
        return loadShorts(new File(filename.toString()), array);
    }
    
    public static short[][] loadShortsBig(final File file) throws IOException {
        return loadShortsBig(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static short[][] loadShortsBig(final CharSequence filename) throws IOException {
        return loadShortsBig(new File(filename.toString()));
    }
    
    public static void storeShorts(final short[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final short[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dataOutput.writeShort(t[d]);
            }
        }
    }
    
    public static void storeShorts(final short[][] array, final DataOutput dataOutput) throws IOException {
        for (int i = 0; i < array.length; ++i) {
            final short[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dataOutput.writeShort(t[d]);
            }
        }
    }
    
    public static void storeShorts(final short[][] array, final long offset, final long length, final File file) throws IOException {
        storeShorts(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeShorts(final short[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeShorts(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeShorts(final short[][] array, final File file) throws IOException {
        storeShorts(array, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeShorts(final short[][] array, final CharSequence filename) throws IOException {
        storeShorts(array, new File(filename.toString()));
    }
    
    public static void storeShorts(final ShortIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeShort(i.nextShort());
        }
    }
    
    public static void storeShorts(final ShortIterator i, final File file) throws IOException {
        storeShorts(i, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeShorts(final ShortIterator i, final CharSequence filename) throws IOException {
        storeShorts(i, new File(filename.toString()));
    }
    
    public static ShortIterator asShortIterator(final DataInput dataInput) {
        return new ShortDataInputWrapper(dataInput);
    }
    
    public static ShortIterator asShortIterator(final File file) throws IOException {
        return asShortIterator(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static ShortIterator asShortIterator(final CharSequence filename) throws IOException {
        return asShortIterator(new File(filename.toString()));
    }
    
    public static ShortIterable asShortIterable(final File file) {
        return () -> {
            try {
                return asShortIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static ShortIterable asShortIterable(final CharSequence filename) {
        return () -> {
            try {
                return asShortIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadInts(final ReadableByteChannel channel, final ByteOrder byteOrder, final int[] array, int offset, int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final IntBuffer buffer = byteBuffer.asIntBuffer();
        int read = 0;
        while (true) {
            byteBuffer.clear();
            byteBuffer.limit();
            int r = channel.read(byteBuffer);
            if (r <= 0) {
                break;
            }
            r >>>= IntMappedBigList.LOG2_BYTES;
            read += r;
            buffer.clear();
            buffer.limit();
            buffer.get(array, offset, r);
            offset += r;
            length -= r;
        }
        return read;
    }
    
    public static int loadInts(final ReadableByteChannel channel, final ByteOrder byteOrder, final int[] array) throws IOException {
        return loadInts(channel, byteOrder, array, 0, array.length);
    }
    
    public static int loadInts(final File file, final ByteOrder byteOrder, final int[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final int read = loadInts(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static int loadInts(final CharSequence filename, final ByteOrder byteOrder, final int[] array, final int offset, final int length) throws IOException {
        return loadInts(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static int loadInts(final File file, final ByteOrder byteOrder, final int[] array) throws IOException {
        return loadInts(file, byteOrder, array, 0, array.length);
    }
    
    public static int loadInts(final CharSequence filename, final ByteOrder byteOrder, final int[] array) throws IOException {
        return loadInts(new File(filename.toString()), byteOrder, array);
    }
    
    public static int[] loadInts(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 4L;
        if (length > 2147483647L) {
            channel.close();
            throw new IllegalArgumentException("File too long: " + channel.size() + " bytes (" + length + " elements)");
        }
        final int[] array = new int[(int)length];
        if (loadInts(channel, byteOrder, array) < length) {
            throw new EOFException();
        }
        channel.close();
        return array;
    }
    
    public static int[] loadInts(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadInts(new File(filename.toString()), byteOrder);
    }
    
    public static void storeInts(final int[] array, int offset, int length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final IntBuffer buffer = byteBuffer.asIntBuffer();
        while (length != 0) {
            final int l = Math.min(length, buffer.capacity());
            buffer.clear();
            buffer.put(array, offset, l);
            buffer.flip();
            byteBuffer.clear();
            byteBuffer.limit();
            channel.write(byteBuffer);
            offset += l;
            length -= l;
        }
    }
    
    public static void storeInts(final int[] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        storeInts(array, 0, array.length, channel, byteOrder);
    }
    
    public static void storeInts(final int[] array, final int offset, final int length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeInts(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeInts(final int[] array, final int offset, final int length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeInts(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeInts(final int[] array, final File file, final ByteOrder byteOrder) throws IOException {
        storeInts(array, 0, array.length, file, byteOrder);
    }
    
    public static void storeInts(final int[] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeInts(array, new File(filename.toString()), byteOrder);
    }
    
    public static long loadInts(final ReadableByteChannel channel, final ByteOrder byteOrder, final int[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long read = 0L;
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int[] t = array[i];
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int e = (int)Math.min(t.length, offset + length - BigArrays.start(i));
            final int r = loadInts(channel, byteOrder, t, s, e - s);
            read += r;
            if (r < e - s) {
                break;
            }
        }
        return read;
    }
    
    public static long loadInts(final ReadableByteChannel channel, final ByteOrder byteOrder, final int[][] array) throws IOException {
        return loadInts(channel, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadInts(final File file, final ByteOrder byteOrder, final int[][] array, final long offset, final long length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadInts(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static long loadInts(final CharSequence filename, final ByteOrder byteOrder, final int[][] array, final long offset, final long length) throws IOException {
        return loadInts(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static long loadInts(final File file, final ByteOrder byteOrder, final int[][] array) throws IOException {
        return loadInts(file, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadInts(final CharSequence filename, final ByteOrder byteOrder, final int[][] array) throws IOException {
        return loadInts(new File(filename.toString()), byteOrder, array);
    }
    
    public static int[][] loadIntsBig(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 4L;
        final int[][] bigArray;
        final int[][] array = bigArray = IntBigArrays.newBigArray(length);
        for (final int[] t : bigArray) {
            loadInts(channel, byteOrder, t);
        }
        channel.close();
        return array;
    }
    
    public static int[][] loadIntsBig(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadIntsBig(new File(filename.toString()), byteOrder);
    }
    
    public static void storeInts(final int[][] array, final long offset, final long length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int l = (int)Math.min(array[i].length, offset + length - BigArrays.start(i));
            storeInts(array[i], s, l - s, channel, byteOrder);
        }
    }
    
    public static void storeInts(final int[][] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (final int[] t : array) {
            storeInts(t, channel, byteOrder);
        }
    }
    
    public static void storeInts(final int[][] array, final long offset, final long length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeInts(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeInts(final int[][] array, final long offset, final long length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeInts(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeInts(final int[][] array, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeInts(array, channel, byteOrder);
        channel.close();
    }
    
    public static void storeInts(final int[][] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeInts(array, new File(filename.toString()), byteOrder);
    }
    
    public static void storeInts(final IntIterator i, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final IntBuffer buffer = byteBuffer.asIntBuffer();
        while (i.hasNext()) {
            if (!buffer.hasRemaining()) {
                buffer.flip();
                byteBuffer.clear();
                byteBuffer.limit();
                channel.write(byteBuffer);
                buffer.clear();
            }
            buffer.put(i.nextInt());
        }
        buffer.flip();
        byteBuffer.clear();
        byteBuffer.limit();
        channel.write(byteBuffer);
    }
    
    public static void storeInts(final IntIterator i, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeInts(i, channel, byteOrder);
        channel.close();
    }
    
    public static void storeInts(final IntIterator i, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeInts(i, new File(filename.toString()), byteOrder);
    }
    
    public static IntIterator asIntIterator(final ReadableByteChannel channel, final ByteOrder byteOrder) {
        return new IntDataNioInputWrapper(channel, byteOrder);
    }
    
    public static IntIterator asIntIterator(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        return new IntDataNioInputWrapper(channel, byteOrder);
    }
    
    public static IntIterator asIntIterator(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return asIntIterator(new File(filename.toString()), byteOrder);
    }
    
    public static IntIterable asIntIterable(final File file, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asIntIterator(file, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static IntIterable asIntIterable(final CharSequence filename, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asIntIterator(filename, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadInts(final DataInput dataInput, final int[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readInt();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadInts(final DataInput dataInput, final int[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readInt();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadInts(final File file, final int[] array, final int offset, final int length) throws IOException {
        return loadInts(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static int loadInts(final CharSequence filename, final int[] array, final int offset, final int length) throws IOException {
        return loadInts(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadInts(final File file, final int[] array) throws IOException {
        return loadInts(file, array, 0, array.length);
    }
    
    public static int loadInts(final CharSequence filename, final int[] array) throws IOException {
        return loadInts(new File(filename.toString()), array);
    }
    
    public static int[] loadInts(final File file) throws IOException {
        return loadInts(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static int[] loadInts(final CharSequence filename) throws IOException {
        return loadInts(new File(filename.toString()));
    }
    
    public static void storeInts(final int[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        for (int i = 0; i < length; ++i) {
            dataOutput.writeInt(array[offset + i]);
        }
    }
    
    public static void storeInts(final int[] array, final DataOutput dataOutput) throws IOException {
        for (int length = array.length, i = 0; i < length; ++i) {
            dataOutput.writeInt(array[i]);
        }
    }
    
    public static void storeInts(final int[] array, final int offset, final int length, final File file) throws IOException {
        storeInts(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeInts(final int[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeInts(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeInts(final int[] array, final File file) throws IOException {
        storeInts(array, 0, array.length, file);
    }
    
    public static void storeInts(final int[] array, final CharSequence filename) throws IOException {
        storeInts(array, new File(filename.toString()));
    }
    
    public static long loadInts(final DataInput dataInput, final int[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final int[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readInt();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadInts(final DataInput dataInput, final int[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final int[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readInt();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadInts(final File file, final int[][] array, final long offset, final long length) throws IOException {
        return loadInts(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static long loadInts(final CharSequence filename, final int[][] array, final long offset, final long length) throws IOException {
        return loadInts(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadInts(final File file, final int[][] array) throws IOException {
        return loadInts(file, ByteOrder.BIG_ENDIAN, array);
    }
    
    public static long loadInts(final CharSequence filename, final int[][] array) throws IOException {
        return loadInts(new File(filename.toString()), array);
    }
    
    public static int[][] loadIntsBig(final File file) throws IOException {
        return loadIntsBig(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static int[][] loadIntsBig(final CharSequence filename) throws IOException {
        return loadIntsBig(new File(filename.toString()));
    }
    
    public static void storeInts(final int[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dataOutput.writeInt(t[d]);
            }
        }
    }
    
    public static void storeInts(final int[][] array, final DataOutput dataOutput) throws IOException {
        for (int i = 0; i < array.length; ++i) {
            final int[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dataOutput.writeInt(t[d]);
            }
        }
    }
    
    public static void storeInts(final int[][] array, final long offset, final long length, final File file) throws IOException {
        storeInts(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeInts(final int[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeInts(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeInts(final int[][] array, final File file) throws IOException {
        storeInts(array, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeInts(final int[][] array, final CharSequence filename) throws IOException {
        storeInts(array, new File(filename.toString()));
    }
    
    public static void storeInts(final IntIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeInt(i.nextInt());
        }
    }
    
    public static void storeInts(final IntIterator i, final File file) throws IOException {
        storeInts(i, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeInts(final IntIterator i, final CharSequence filename) throws IOException {
        storeInts(i, new File(filename.toString()));
    }
    
    public static IntIterator asIntIterator(final DataInput dataInput) {
        return new IntDataInputWrapper(dataInput);
    }
    
    public static IntIterator asIntIterator(final File file) throws IOException {
        return asIntIterator(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static IntIterator asIntIterator(final CharSequence filename) throws IOException {
        return asIntIterator(new File(filename.toString()));
    }
    
    public static IntIterable asIntIterable(final File file) {
        return () -> {
            try {
                return asIntIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static IntIterable asIntIterable(final CharSequence filename) {
        return () -> {
            try {
                return asIntIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadFloats(final ReadableByteChannel channel, final ByteOrder byteOrder, final float[] array, int offset, int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final FloatBuffer buffer = byteBuffer.asFloatBuffer();
        int read = 0;
        while (true) {
            byteBuffer.clear();
            byteBuffer.limit();
            int r = channel.read(byteBuffer);
            if (r <= 0) {
                break;
            }
            r >>>= FloatMappedBigList.LOG2_BYTES;
            read += r;
            buffer.clear();
            buffer.limit();
            buffer.get(array, offset, r);
            offset += r;
            length -= r;
        }
        return read;
    }
    
    public static int loadFloats(final ReadableByteChannel channel, final ByteOrder byteOrder, final float[] array) throws IOException {
        return loadFloats(channel, byteOrder, array, 0, array.length);
    }
    
    public static int loadFloats(final File file, final ByteOrder byteOrder, final float[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final int read = loadFloats(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static int loadFloats(final CharSequence filename, final ByteOrder byteOrder, final float[] array, final int offset, final int length) throws IOException {
        return loadFloats(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static int loadFloats(final File file, final ByteOrder byteOrder, final float[] array) throws IOException {
        return loadFloats(file, byteOrder, array, 0, array.length);
    }
    
    public static int loadFloats(final CharSequence filename, final ByteOrder byteOrder, final float[] array) throws IOException {
        return loadFloats(new File(filename.toString()), byteOrder, array);
    }
    
    public static float[] loadFloats(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 4L;
        if (length > 2147483647L) {
            channel.close();
            throw new IllegalArgumentException("File too long: " + channel.size() + " bytes (" + length + " elements)");
        }
        final float[] array = new float[(int)length];
        if (loadFloats(channel, byteOrder, array) < length) {
            throw new EOFException();
        }
        channel.close();
        return array;
    }
    
    public static float[] loadFloats(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadFloats(new File(filename.toString()), byteOrder);
    }
    
    public static void storeFloats(final float[] array, int offset, int length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final FloatBuffer buffer = byteBuffer.asFloatBuffer();
        while (length != 0) {
            final int l = Math.min(length, buffer.capacity());
            buffer.clear();
            buffer.put(array, offset, l);
            buffer.flip();
            byteBuffer.clear();
            byteBuffer.limit();
            channel.write(byteBuffer);
            offset += l;
            length -= l;
        }
    }
    
    public static void storeFloats(final float[] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        storeFloats(array, 0, array.length, channel, byteOrder);
    }
    
    public static void storeFloats(final float[] array, final int offset, final int length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeFloats(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeFloats(final float[] array, final int offset, final int length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeFloats(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeFloats(final float[] array, final File file, final ByteOrder byteOrder) throws IOException {
        storeFloats(array, 0, array.length, file, byteOrder);
    }
    
    public static void storeFloats(final float[] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeFloats(array, new File(filename.toString()), byteOrder);
    }
    
    public static long loadFloats(final ReadableByteChannel channel, final ByteOrder byteOrder, final float[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long read = 0L;
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final float[] t = array[i];
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int e = (int)Math.min(t.length, offset + length - BigArrays.start(i));
            final int r = loadFloats(channel, byteOrder, t, s, e - s);
            read += r;
            if (r < e - s) {
                break;
            }
        }
        return read;
    }
    
    public static long loadFloats(final ReadableByteChannel channel, final ByteOrder byteOrder, final float[][] array) throws IOException {
        return loadFloats(channel, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadFloats(final File file, final ByteOrder byteOrder, final float[][] array, final long offset, final long length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadFloats(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static long loadFloats(final CharSequence filename, final ByteOrder byteOrder, final float[][] array, final long offset, final long length) throws IOException {
        return loadFloats(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static long loadFloats(final File file, final ByteOrder byteOrder, final float[][] array) throws IOException {
        return loadFloats(file, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadFloats(final CharSequence filename, final ByteOrder byteOrder, final float[][] array) throws IOException {
        return loadFloats(new File(filename.toString()), byteOrder, array);
    }
    
    public static float[][] loadFloatsBig(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 4L;
        final float[][] bigArray;
        final float[][] array = bigArray = FloatBigArrays.newBigArray(length);
        for (final float[] t : bigArray) {
            loadFloats(channel, byteOrder, t);
        }
        channel.close();
        return array;
    }
    
    public static float[][] loadFloatsBig(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadFloatsBig(new File(filename.toString()), byteOrder);
    }
    
    public static void storeFloats(final float[][] array, final long offset, final long length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int l = (int)Math.min(array[i].length, offset + length - BigArrays.start(i));
            storeFloats(array[i], s, l - s, channel, byteOrder);
        }
    }
    
    public static void storeFloats(final float[][] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (final float[] t : array) {
            storeFloats(t, channel, byteOrder);
        }
    }
    
    public static void storeFloats(final float[][] array, final long offset, final long length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeFloats(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeFloats(final float[][] array, final long offset, final long length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeFloats(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeFloats(final float[][] array, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeFloats(array, channel, byteOrder);
        channel.close();
    }
    
    public static void storeFloats(final float[][] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeFloats(array, new File(filename.toString()), byteOrder);
    }
    
    public static void storeFloats(final FloatIterator i, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final FloatBuffer buffer = byteBuffer.asFloatBuffer();
        while (i.hasNext()) {
            if (!buffer.hasRemaining()) {
                buffer.flip();
                byteBuffer.clear();
                byteBuffer.limit();
                channel.write(byteBuffer);
                buffer.clear();
            }
            buffer.put(i.nextFloat());
        }
        buffer.flip();
        byteBuffer.clear();
        byteBuffer.limit();
        channel.write(byteBuffer);
    }
    
    public static void storeFloats(final FloatIterator i, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeFloats(i, channel, byteOrder);
        channel.close();
    }
    
    public static void storeFloats(final FloatIterator i, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeFloats(i, new File(filename.toString()), byteOrder);
    }
    
    public static FloatIterator asFloatIterator(final ReadableByteChannel channel, final ByteOrder byteOrder) {
        return new FloatDataNioInputWrapper(channel, byteOrder);
    }
    
    public static FloatIterator asFloatIterator(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        return new FloatDataNioInputWrapper(channel, byteOrder);
    }
    
    public static FloatIterator asFloatIterator(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return asFloatIterator(new File(filename.toString()), byteOrder);
    }
    
    public static FloatIterable asFloatIterable(final File file, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asFloatIterator(file, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static FloatIterable asFloatIterable(final CharSequence filename, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asFloatIterator(filename, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadFloats(final DataInput dataInput, final float[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readFloat();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadFloats(final DataInput dataInput, final float[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readFloat();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadFloats(final File file, final float[] array, final int offset, final int length) throws IOException {
        return loadFloats(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static int loadFloats(final CharSequence filename, final float[] array, final int offset, final int length) throws IOException {
        return loadFloats(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadFloats(final File file, final float[] array) throws IOException {
        return loadFloats(file, array, 0, array.length);
    }
    
    public static int loadFloats(final CharSequence filename, final float[] array) throws IOException {
        return loadFloats(new File(filename.toString()), array);
    }
    
    public static float[] loadFloats(final File file) throws IOException {
        return loadFloats(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static float[] loadFloats(final CharSequence filename) throws IOException {
        return loadFloats(new File(filename.toString()));
    }
    
    public static void storeFloats(final float[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        for (int i = 0; i < length; ++i) {
            dataOutput.writeFloat(array[offset + i]);
        }
    }
    
    public static void storeFloats(final float[] array, final DataOutput dataOutput) throws IOException {
        for (int length = array.length, i = 0; i < length; ++i) {
            dataOutput.writeFloat(array[i]);
        }
    }
    
    public static void storeFloats(final float[] array, final int offset, final int length, final File file) throws IOException {
        storeFloats(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeFloats(final float[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeFloats(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeFloats(final float[] array, final File file) throws IOException {
        storeFloats(array, 0, array.length, file);
    }
    
    public static void storeFloats(final float[] array, final CharSequence filename) throws IOException {
        storeFloats(array, new File(filename.toString()));
    }
    
    public static long loadFloats(final DataInput dataInput, final float[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final float[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readFloat();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadFloats(final DataInput dataInput, final float[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final float[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readFloat();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadFloats(final File file, final float[][] array, final long offset, final long length) throws IOException {
        return loadFloats(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static long loadFloats(final CharSequence filename, final float[][] array, final long offset, final long length) throws IOException {
        return loadFloats(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadFloats(final File file, final float[][] array) throws IOException {
        return loadFloats(file, ByteOrder.BIG_ENDIAN, array);
    }
    
    public static long loadFloats(final CharSequence filename, final float[][] array) throws IOException {
        return loadFloats(new File(filename.toString()), array);
    }
    
    public static float[][] loadFloatsBig(final File file) throws IOException {
        return loadFloatsBig(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static float[][] loadFloatsBig(final CharSequence filename) throws IOException {
        return loadFloatsBig(new File(filename.toString()));
    }
    
    public static void storeFloats(final float[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final float[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dataOutput.writeFloat(t[d]);
            }
        }
    }
    
    public static void storeFloats(final float[][] array, final DataOutput dataOutput) throws IOException {
        for (int i = 0; i < array.length; ++i) {
            final float[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dataOutput.writeFloat(t[d]);
            }
        }
    }
    
    public static void storeFloats(final float[][] array, final long offset, final long length, final File file) throws IOException {
        storeFloats(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeFloats(final float[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeFloats(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeFloats(final float[][] array, final File file) throws IOException {
        storeFloats(array, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeFloats(final float[][] array, final CharSequence filename) throws IOException {
        storeFloats(array, new File(filename.toString()));
    }
    
    public static void storeFloats(final FloatIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeFloat(i.nextFloat());
        }
    }
    
    public static void storeFloats(final FloatIterator i, final File file) throws IOException {
        storeFloats(i, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeFloats(final FloatIterator i, final CharSequence filename) throws IOException {
        storeFloats(i, new File(filename.toString()));
    }
    
    public static FloatIterator asFloatIterator(final DataInput dataInput) {
        return new FloatDataInputWrapper(dataInput);
    }
    
    public static FloatIterator asFloatIterator(final File file) throws IOException {
        return asFloatIterator(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static FloatIterator asFloatIterator(final CharSequence filename) throws IOException {
        return asFloatIterator(new File(filename.toString()));
    }
    
    public static FloatIterable asFloatIterable(final File file) {
        return () -> {
            try {
                return asFloatIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static FloatIterable asFloatIterable(final CharSequence filename) {
        return () -> {
            try {
                return asFloatIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadLongs(final ReadableByteChannel channel, final ByteOrder byteOrder, final long[] array, int offset, int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final LongBuffer buffer = byteBuffer.asLongBuffer();
        int read = 0;
        while (true) {
            byteBuffer.clear();
            byteBuffer.limit();
            int r = channel.read(byteBuffer);
            if (r <= 0) {
                break;
            }
            r >>>= LongMappedBigList.LOG2_BYTES;
            read += r;
            buffer.clear();
            buffer.limit();
            buffer.get(array, offset, r);
            offset += r;
            length -= r;
        }
        return read;
    }
    
    public static int loadLongs(final ReadableByteChannel channel, final ByteOrder byteOrder, final long[] array) throws IOException {
        return loadLongs(channel, byteOrder, array, 0, array.length);
    }
    
    public static int loadLongs(final File file, final ByteOrder byteOrder, final long[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final int read = loadLongs(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static int loadLongs(final CharSequence filename, final ByteOrder byteOrder, final long[] array, final int offset, final int length) throws IOException {
        return loadLongs(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static int loadLongs(final File file, final ByteOrder byteOrder, final long[] array) throws IOException {
        return loadLongs(file, byteOrder, array, 0, array.length);
    }
    
    public static int loadLongs(final CharSequence filename, final ByteOrder byteOrder, final long[] array) throws IOException {
        return loadLongs(new File(filename.toString()), byteOrder, array);
    }
    
    public static long[] loadLongs(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 8L;
        if (length > 2147483647L) {
            channel.close();
            throw new IllegalArgumentException("File too long: " + channel.size() + " bytes (" + length + " elements)");
        }
        final long[] array = new long[(int)length];
        if (loadLongs(channel, byteOrder, array) < length) {
            throw new EOFException();
        }
        channel.close();
        return array;
    }
    
    public static long[] loadLongs(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadLongs(new File(filename.toString()), byteOrder);
    }
    
    public static void storeLongs(final long[] array, int offset, int length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final LongBuffer buffer = byteBuffer.asLongBuffer();
        while (length != 0) {
            final int l = Math.min(length, buffer.capacity());
            buffer.clear();
            buffer.put(array, offset, l);
            buffer.flip();
            byteBuffer.clear();
            byteBuffer.limit();
            channel.write(byteBuffer);
            offset += l;
            length -= l;
        }
    }
    
    public static void storeLongs(final long[] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        storeLongs(array, 0, array.length, channel, byteOrder);
    }
    
    public static void storeLongs(final long[] array, final int offset, final int length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeLongs(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeLongs(final long[] array, final int offset, final int length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeLongs(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeLongs(final long[] array, final File file, final ByteOrder byteOrder) throws IOException {
        storeLongs(array, 0, array.length, file, byteOrder);
    }
    
    public static void storeLongs(final long[] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeLongs(array, new File(filename.toString()), byteOrder);
    }
    
    public static long loadLongs(final ReadableByteChannel channel, final ByteOrder byteOrder, final long[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long read = 0L;
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final long[] t = array[i];
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int e = (int)Math.min(t.length, offset + length - BigArrays.start(i));
            final int r = loadLongs(channel, byteOrder, t, s, e - s);
            read += r;
            if (r < e - s) {
                break;
            }
        }
        return read;
    }
    
    public static long loadLongs(final ReadableByteChannel channel, final ByteOrder byteOrder, final long[][] array) throws IOException {
        return loadLongs(channel, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadLongs(final File file, final ByteOrder byteOrder, final long[][] array, final long offset, final long length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadLongs(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static long loadLongs(final CharSequence filename, final ByteOrder byteOrder, final long[][] array, final long offset, final long length) throws IOException {
        return loadLongs(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static long loadLongs(final File file, final ByteOrder byteOrder, final long[][] array) throws IOException {
        return loadLongs(file, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadLongs(final CharSequence filename, final ByteOrder byteOrder, final long[][] array) throws IOException {
        return loadLongs(new File(filename.toString()), byteOrder, array);
    }
    
    public static long[][] loadLongsBig(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 8L;
        final long[][] bigArray;
        final long[][] array = bigArray = LongBigArrays.newBigArray(length);
        for (final long[] t : bigArray) {
            loadLongs(channel, byteOrder, t);
        }
        channel.close();
        return array;
    }
    
    public static long[][] loadLongsBig(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadLongsBig(new File(filename.toString()), byteOrder);
    }
    
    public static void storeLongs(final long[][] array, final long offset, final long length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int l = (int)Math.min(array[i].length, offset + length - BigArrays.start(i));
            storeLongs(array[i], s, l - s, channel, byteOrder);
        }
    }
    
    public static void storeLongs(final long[][] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (final long[] t : array) {
            storeLongs(t, channel, byteOrder);
        }
    }
    
    public static void storeLongs(final long[][] array, final long offset, final long length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeLongs(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeLongs(final long[][] array, final long offset, final long length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeLongs(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeLongs(final long[][] array, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeLongs(array, channel, byteOrder);
        channel.close();
    }
    
    public static void storeLongs(final long[][] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeLongs(array, new File(filename.toString()), byteOrder);
    }
    
    public static void storeLongs(final LongIterator i, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final LongBuffer buffer = byteBuffer.asLongBuffer();
        while (i.hasNext()) {
            if (!buffer.hasRemaining()) {
                buffer.flip();
                byteBuffer.clear();
                byteBuffer.limit();
                channel.write(byteBuffer);
                buffer.clear();
            }
            buffer.put(i.nextLong());
        }
        buffer.flip();
        byteBuffer.clear();
        byteBuffer.limit();
        channel.write(byteBuffer);
    }
    
    public static void storeLongs(final LongIterator i, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeLongs(i, channel, byteOrder);
        channel.close();
    }
    
    public static void storeLongs(final LongIterator i, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeLongs(i, new File(filename.toString()), byteOrder);
    }
    
    public static LongIterator asLongIterator(final ReadableByteChannel channel, final ByteOrder byteOrder) {
        return new LongDataNioInputWrapper(channel, byteOrder);
    }
    
    public static LongIterator asLongIterator(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        return new LongDataNioInputWrapper(channel, byteOrder);
    }
    
    public static LongIterator asLongIterator(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return asLongIterator(new File(filename.toString()), byteOrder);
    }
    
    public static LongIterable asLongIterable(final File file, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asLongIterator(file, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static LongIterable asLongIterable(final CharSequence filename, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asLongIterator(filename, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadLongs(final DataInput dataInput, final long[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readLong();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadLongs(final DataInput dataInput, final long[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readLong();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadLongs(final File file, final long[] array, final int offset, final int length) throws IOException {
        return loadLongs(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static int loadLongs(final CharSequence filename, final long[] array, final int offset, final int length) throws IOException {
        return loadLongs(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadLongs(final File file, final long[] array) throws IOException {
        return loadLongs(file, array, 0, array.length);
    }
    
    public static int loadLongs(final CharSequence filename, final long[] array) throws IOException {
        return loadLongs(new File(filename.toString()), array);
    }
    
    public static long[] loadLongs(final File file) throws IOException {
        return loadLongs(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static long[] loadLongs(final CharSequence filename) throws IOException {
        return loadLongs(new File(filename.toString()));
    }
    
    public static void storeLongs(final long[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        for (int i = 0; i < length; ++i) {
            dataOutput.writeLong(array[offset + i]);
        }
    }
    
    public static void storeLongs(final long[] array, final DataOutput dataOutput) throws IOException {
        for (int length = array.length, i = 0; i < length; ++i) {
            dataOutput.writeLong(array[i]);
        }
    }
    
    public static void storeLongs(final long[] array, final int offset, final int length, final File file) throws IOException {
        storeLongs(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeLongs(final long[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeLongs(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeLongs(final long[] array, final File file) throws IOException {
        storeLongs(array, 0, array.length, file);
    }
    
    public static void storeLongs(final long[] array, final CharSequence filename) throws IOException {
        storeLongs(array, new File(filename.toString()));
    }
    
    public static long loadLongs(final DataInput dataInput, final long[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final long[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readLong();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadLongs(final DataInput dataInput, final long[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final long[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readLong();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadLongs(final File file, final long[][] array, final long offset, final long length) throws IOException {
        return loadLongs(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static long loadLongs(final CharSequence filename, final long[][] array, final long offset, final long length) throws IOException {
        return loadLongs(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadLongs(final File file, final long[][] array) throws IOException {
        return loadLongs(file, ByteOrder.BIG_ENDIAN, array);
    }
    
    public static long loadLongs(final CharSequence filename, final long[][] array) throws IOException {
        return loadLongs(new File(filename.toString()), array);
    }
    
    public static long[][] loadLongsBig(final File file) throws IOException {
        return loadLongsBig(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static long[][] loadLongsBig(final CharSequence filename) throws IOException {
        return loadLongsBig(new File(filename.toString()));
    }
    
    public static void storeLongs(final long[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final long[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dataOutput.writeLong(t[d]);
            }
        }
    }
    
    public static void storeLongs(final long[][] array, final DataOutput dataOutput) throws IOException {
        for (int i = 0; i < array.length; ++i) {
            final long[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dataOutput.writeLong(t[d]);
            }
        }
    }
    
    public static void storeLongs(final long[][] array, final long offset, final long length, final File file) throws IOException {
        storeLongs(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeLongs(final long[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeLongs(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeLongs(final long[][] array, final File file) throws IOException {
        storeLongs(array, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeLongs(final long[][] array, final CharSequence filename) throws IOException {
        storeLongs(array, new File(filename.toString()));
    }
    
    public static void storeLongs(final LongIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeLong(i.nextLong());
        }
    }
    
    public static void storeLongs(final LongIterator i, final File file) throws IOException {
        storeLongs(i, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeLongs(final LongIterator i, final CharSequence filename) throws IOException {
        storeLongs(i, new File(filename.toString()));
    }
    
    public static LongIterator asLongIterator(final DataInput dataInput) {
        return new LongDataInputWrapper(dataInput);
    }
    
    public static LongIterator asLongIterator(final File file) throws IOException {
        return asLongIterator(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static LongIterator asLongIterator(final CharSequence filename) throws IOException {
        return asLongIterator(new File(filename.toString()));
    }
    
    public static LongIterable asLongIterable(final File file) {
        return () -> {
            try {
                return asLongIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static LongIterable asLongIterable(final CharSequence filename) {
        return () -> {
            try {
                return asLongIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadDoubles(final ReadableByteChannel channel, final ByteOrder byteOrder, final double[] array, int offset, int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final DoubleBuffer buffer = byteBuffer.asDoubleBuffer();
        int read = 0;
        while (true) {
            byteBuffer.clear();
            byteBuffer.limit();
            int r = channel.read(byteBuffer);
            if (r <= 0) {
                break;
            }
            r >>>= DoubleMappedBigList.LOG2_BYTES;
            read += r;
            buffer.clear();
            buffer.limit();
            buffer.get(array, offset, r);
            offset += r;
            length -= r;
        }
        return read;
    }
    
    public static int loadDoubles(final ReadableByteChannel channel, final ByteOrder byteOrder, final double[] array) throws IOException {
        return loadDoubles(channel, byteOrder, array, 0, array.length);
    }
    
    public static int loadDoubles(final File file, final ByteOrder byteOrder, final double[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final int read = loadDoubles(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static int loadDoubles(final CharSequence filename, final ByteOrder byteOrder, final double[] array, final int offset, final int length) throws IOException {
        return loadDoubles(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static int loadDoubles(final File file, final ByteOrder byteOrder, final double[] array) throws IOException {
        return loadDoubles(file, byteOrder, array, 0, array.length);
    }
    
    public static int loadDoubles(final CharSequence filename, final ByteOrder byteOrder, final double[] array) throws IOException {
        return loadDoubles(new File(filename.toString()), byteOrder, array);
    }
    
    public static double[] loadDoubles(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 8L;
        if (length > 2147483647L) {
            channel.close();
            throw new IllegalArgumentException("File too long: " + channel.size() + " bytes (" + length + " elements)");
        }
        final double[] array = new double[(int)length];
        if (loadDoubles(channel, byteOrder, array) < length) {
            throw new EOFException();
        }
        channel.close();
        return array;
    }
    
    public static double[] loadDoubles(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadDoubles(new File(filename.toString()), byteOrder);
    }
    
    public static void storeDoubles(final double[] array, int offset, int length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final DoubleBuffer buffer = byteBuffer.asDoubleBuffer();
        while (length != 0) {
            final int l = Math.min(length, buffer.capacity());
            buffer.clear();
            buffer.put(array, offset, l);
            buffer.flip();
            byteBuffer.clear();
            byteBuffer.limit();
            channel.write(byteBuffer);
            offset += l;
            length -= l;
        }
    }
    
    public static void storeDoubles(final double[] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        storeDoubles(array, 0, array.length, channel, byteOrder);
    }
    
    public static void storeDoubles(final double[] array, final int offset, final int length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeDoubles(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeDoubles(final double[] array, final int offset, final int length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeDoubles(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeDoubles(final double[] array, final File file, final ByteOrder byteOrder) throws IOException {
        storeDoubles(array, 0, array.length, file, byteOrder);
    }
    
    public static void storeDoubles(final double[] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeDoubles(array, new File(filename.toString()), byteOrder);
    }
    
    public static long loadDoubles(final ReadableByteChannel channel, final ByteOrder byteOrder, final double[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long read = 0L;
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final double[] t = array[i];
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int e = (int)Math.min(t.length, offset + length - BigArrays.start(i));
            final int r = loadDoubles(channel, byteOrder, t, s, e - s);
            read += r;
            if (r < e - s) {
                break;
            }
        }
        return read;
    }
    
    public static long loadDoubles(final ReadableByteChannel channel, final ByteOrder byteOrder, final double[][] array) throws IOException {
        return loadDoubles(channel, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadDoubles(final File file, final ByteOrder byteOrder, final double[][] array, final long offset, final long length) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long read = loadDoubles(channel, byteOrder, array, offset, length);
        channel.close();
        return read;
    }
    
    public static long loadDoubles(final CharSequence filename, final ByteOrder byteOrder, final double[][] array, final long offset, final long length) throws IOException {
        return loadDoubles(new File(filename.toString()), byteOrder, array, offset, length);
    }
    
    public static long loadDoubles(final File file, final ByteOrder byteOrder, final double[][] array) throws IOException {
        return loadDoubles(file, byteOrder, array, 0L, BigArrays.length(array));
    }
    
    public static long loadDoubles(final CharSequence filename, final ByteOrder byteOrder, final double[][] array) throws IOException {
        return loadDoubles(new File(filename.toString()), byteOrder, array);
    }
    
    public static double[][] loadDoublesBig(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        final long length = channel.size() / 8L;
        final double[][] bigArray;
        final double[][] array = bigArray = DoubleBigArrays.newBigArray(length);
        for (final double[] t : bigArray) {
            loadDoubles(channel, byteOrder, t);
        }
        channel.close();
        return array;
    }
    
    public static double[][] loadDoublesBig(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return loadDoublesBig(new File(filename.toString()), byteOrder);
    }
    
    public static void storeDoubles(final double[][] array, final long offset, final long length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final int s = (int)Math.max(0L, offset - BigArrays.start(i));
            final int l = (int)Math.min(array[i].length, offset + length - BigArrays.start(i));
            storeDoubles(array[i], s, l - s, channel, byteOrder);
        }
    }
    
    public static void storeDoubles(final double[][] array, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        for (final double[] t : array) {
            storeDoubles(t, channel, byteOrder);
        }
    }
    
    public static void storeDoubles(final double[][] array, final long offset, final long length, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeDoubles(array, offset, length, channel, byteOrder);
        channel.close();
    }
    
    public static void storeDoubles(final double[][] array, final long offset, final long length, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeDoubles(array, offset, length, new File(filename.toString()), byteOrder);
    }
    
    public static void storeDoubles(final double[][] array, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeDoubles(array, channel, byteOrder);
        channel.close();
    }
    
    public static void storeDoubles(final double[][] array, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeDoubles(array, new File(filename.toString()), byteOrder);
    }
    
    public static void storeDoubles(final DoubleIterator i, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException {
        final ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
        final DoubleBuffer buffer = byteBuffer.asDoubleBuffer();
        while (i.hasNext()) {
            if (!buffer.hasRemaining()) {
                buffer.flip();
                byteBuffer.clear();
                byteBuffer.limit();
                channel.write(byteBuffer);
                buffer.clear();
            }
            buffer.put(i.nextDouble());
        }
        buffer.flip();
        byteBuffer.clear();
        byteBuffer.limit();
        channel.write(byteBuffer);
    }
    
    public static void storeDoubles(final DoubleIterator i, final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
        storeDoubles(i, channel, byteOrder);
        channel.close();
    }
    
    public static void storeDoubles(final DoubleIterator i, final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        storeDoubles(i, new File(filename.toString()), byteOrder);
    }
    
    public static DoubleIterator asDoubleIterator(final ReadableByteChannel channel, final ByteOrder byteOrder) {
        return new DoubleDataNioInputWrapper(channel, byteOrder);
    }
    
    public static DoubleIterator asDoubleIterator(final File file, final ByteOrder byteOrder) throws IOException {
        final FileChannel channel = FileChannel.open(file.toPath(), new OpenOption[0]);
        return new DoubleDataNioInputWrapper(channel, byteOrder);
    }
    
    public static DoubleIterator asDoubleIterator(final CharSequence filename, final ByteOrder byteOrder) throws IOException {
        return asDoubleIterator(new File(filename.toString()), byteOrder);
    }
    
    public static DoubleIterable asDoubleIterable(final File file, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asDoubleIterator(file, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static DoubleIterable asDoubleIterable(final CharSequence filename, final ByteOrder byteOrder) {
        return () -> {
            try {
                return asDoubleIterator(filename, byteOrder);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static int loadDoubles(final DataInput dataInput, final double[] array, final int offset, final int length) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        int i = 0;
        try {
            for (i = 0; i < length; ++i) {
                array[i + offset] = dataInput.readDouble();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadDoubles(final DataInput dataInput, final double[] array) throws IOException {
        int i = 0;
        try {
            for (final int length = array.length, i = 0; i < length; ++i) {
                array[i] = dataInput.readDouble();
            }
        }
        catch (final EOFException ex) {}
        return i;
    }
    
    public static int loadDoubles(final File file, final double[] array, final int offset, final int length) throws IOException {
        return loadDoubles(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static int loadDoubles(final CharSequence filename, final double[] array, final int offset, final int length) throws IOException {
        return loadDoubles(new File(filename.toString()), array, offset, length);
    }
    
    public static int loadDoubles(final File file, final double[] array) throws IOException {
        return loadDoubles(file, array, 0, array.length);
    }
    
    public static int loadDoubles(final CharSequence filename, final double[] array) throws IOException {
        return loadDoubles(new File(filename.toString()), array);
    }
    
    public static double[] loadDoubles(final File file) throws IOException {
        return loadDoubles(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static double[] loadDoubles(final CharSequence filename) throws IOException {
        return loadDoubles(new File(filename.toString()));
    }
    
    public static void storeDoubles(final double[] array, final int offset, final int length, final DataOutput dataOutput) throws IOException {
        Arrays.ensureOffsetLength(array.length, offset, length);
        for (int i = 0; i < length; ++i) {
            dataOutput.writeDouble(array[offset + i]);
        }
    }
    
    public static void storeDoubles(final double[] array, final DataOutput dataOutput) throws IOException {
        for (int length = array.length, i = 0; i < length; ++i) {
            dataOutput.writeDouble(array[i]);
        }
    }
    
    public static void storeDoubles(final double[] array, final int offset, final int length, final File file) throws IOException {
        storeDoubles(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeDoubles(final double[] array, final int offset, final int length, final CharSequence filename) throws IOException {
        storeDoubles(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeDoubles(final double[] array, final File file) throws IOException {
        storeDoubles(array, 0, array.length, file);
    }
    
    public static void storeDoubles(final double[] array, final CharSequence filename) throws IOException {
        storeDoubles(array, new File(filename.toString()));
    }
    
    public static long loadDoubles(final DataInput dataInput, final double[][] array, final long offset, final long length) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        long c = 0L;
        try {
            for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
                final double[] t = array[i];
                for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                    t[d] = dataInput.readDouble();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadDoubles(final DataInput dataInput, final double[][] array) throws IOException {
        long c = 0L;
        try {
            for (int i = 0; i < array.length; ++i) {
                final double[] t = array[i];
                for (int l = t.length, d = 0; d < l; ++d) {
                    t[d] = dataInput.readDouble();
                    ++c;
                }
            }
        }
        catch (final EOFException ex) {}
        return c;
    }
    
    public static long loadDoubles(final File file, final double[][] array, final long offset, final long length) throws IOException {
        return loadDoubles(file, ByteOrder.BIG_ENDIAN, array, offset, length);
    }
    
    public static long loadDoubles(final CharSequence filename, final double[][] array, final long offset, final long length) throws IOException {
        return loadDoubles(new File(filename.toString()), array, offset, length);
    }
    
    public static long loadDoubles(final File file, final double[][] array) throws IOException {
        return loadDoubles(file, ByteOrder.BIG_ENDIAN, array);
    }
    
    public static long loadDoubles(final CharSequence filename, final double[][] array) throws IOException {
        return loadDoubles(new File(filename.toString()), array);
    }
    
    public static double[][] loadDoublesBig(final File file) throws IOException {
        return loadDoublesBig(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static double[][] loadDoublesBig(final CharSequence filename) throws IOException {
        return loadDoublesBig(new File(filename.toString()));
    }
    
    public static void storeDoubles(final double[][] array, final long offset, final long length, final DataOutput dataOutput) throws IOException {
        BigArrays.ensureOffsetLength(array, offset, length);
        for (int i = BigArrays.segment(offset); i < BigArrays.segment(offset + length + 134217727L); ++i) {
            final double[] t = array[i];
            for (int l = (int)Math.min(t.length, offset + length - BigArrays.start(i)), d = (int)Math.max(0L, offset - BigArrays.start(i)); d < l; ++d) {
                dataOutput.writeDouble(t[d]);
            }
        }
    }
    
    public static void storeDoubles(final double[][] array, final DataOutput dataOutput) throws IOException {
        for (int i = 0; i < array.length; ++i) {
            final double[] t = array[i];
            for (int l = t.length, d = 0; d < l; ++d) {
                dataOutput.writeDouble(t[d]);
            }
        }
    }
    
    public static void storeDoubles(final double[][] array, final long offset, final long length, final File file) throws IOException {
        storeDoubles(array, offset, length, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeDoubles(final double[][] array, final long offset, final long length, final CharSequence filename) throws IOException {
        storeDoubles(array, offset, length, new File(filename.toString()));
    }
    
    public static void storeDoubles(final double[][] array, final File file) throws IOException {
        storeDoubles(array, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeDoubles(final double[][] array, final CharSequence filename) throws IOException {
        storeDoubles(array, new File(filename.toString()));
    }
    
    public static void storeDoubles(final DoubleIterator i, final DataOutput dataOutput) throws IOException {
        while (i.hasNext()) {
            dataOutput.writeDouble(i.nextDouble());
        }
    }
    
    public static void storeDoubles(final DoubleIterator i, final File file) throws IOException {
        storeDoubles(i, file, ByteOrder.BIG_ENDIAN);
    }
    
    public static void storeDoubles(final DoubleIterator i, final CharSequence filename) throws IOException {
        storeDoubles(i, new File(filename.toString()));
    }
    
    public static DoubleIterator asDoubleIterator(final DataInput dataInput) {
        return new DoubleDataInputWrapper(dataInput);
    }
    
    public static DoubleIterator asDoubleIterator(final File file) throws IOException {
        return asDoubleIterator(file, ByteOrder.BIG_ENDIAN);
    }
    
    public static DoubleIterator asDoubleIterator(final CharSequence filename) throws IOException {
        return asDoubleIterator(new File(filename.toString()));
    }
    
    public static DoubleIterable asDoubleIterable(final File file) {
        return () -> {
            try {
                return asDoubleIterator(file);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    public static DoubleIterable asDoubleIterable(final CharSequence filename) {
        return () -> {
            try {
                return asDoubleIterator(filename);
            }
            catch (final IOException e) {
                throw new RuntimeException(e);
            }
        };
    }
    
    static {
        BinIO.BUFFER_SIZE = 8192;
    }
    
    private static final class BooleanDataInputWrapper implements BooleanIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private boolean next;
        
        public BooleanDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readBoolean();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public boolean nextBoolean() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
    
    private static final class ByteDataInputWrapper implements ByteIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private byte next;
        
        public ByteDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readByte();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public byte nextByte() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
    
    private static final class CharDataNioInputWrapper implements CharIterator
    {
        private final ReadableByteChannel channel;
        private final ByteBuffer byteBuffer;
        private final CharBuffer buffer;
        
        public CharDataNioInputWrapper(final ReadableByteChannel channel, final ByteOrder byteOrder) {
            this.channel = channel;
            this.byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
            this.buffer = this.byteBuffer.asCharBuffer();
            this.buffer.clear().flip();
        }
        
        @Override
        public boolean hasNext() {
            if (!this.buffer.hasRemaining()) {
                this.byteBuffer.clear();
                try {
                    this.channel.read(this.byteBuffer);
                }
                catch (final IOException e) {
                    throw new RuntimeException(e);
                }
                this.byteBuffer.flip();
                this.buffer.clear();
                this.buffer.limit();
            }
            return this.buffer.hasRemaining();
        }
        
        @Override
        public char nextChar() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            return this.buffer.get();
        }
    }
    
    private static final class CharDataInputWrapper implements CharIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private char next;
        
        public CharDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readChar();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public char nextChar() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
    
    private static final class ShortDataNioInputWrapper implements ShortIterator
    {
        private final ReadableByteChannel channel;
        private final ByteBuffer byteBuffer;
        private final ShortBuffer buffer;
        
        public ShortDataNioInputWrapper(final ReadableByteChannel channel, final ByteOrder byteOrder) {
            this.channel = channel;
            this.byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
            this.buffer = this.byteBuffer.asShortBuffer();
            this.buffer.clear().flip();
        }
        
        @Override
        public boolean hasNext() {
            if (!this.buffer.hasRemaining()) {
                this.byteBuffer.clear();
                try {
                    this.channel.read(this.byteBuffer);
                }
                catch (final IOException e) {
                    throw new RuntimeException(e);
                }
                this.byteBuffer.flip();
                this.buffer.clear();
                this.buffer.limit();
            }
            return this.buffer.hasRemaining();
        }
        
        @Override
        public short nextShort() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            return this.buffer.get();
        }
    }
    
    private static final class ShortDataInputWrapper implements ShortIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private short next;
        
        public ShortDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readShort();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public short nextShort() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
    
    private static final class IntDataNioInputWrapper implements IntIterator
    {
        private final ReadableByteChannel channel;
        private final ByteBuffer byteBuffer;
        private final IntBuffer buffer;
        
        public IntDataNioInputWrapper(final ReadableByteChannel channel, final ByteOrder byteOrder) {
            this.channel = channel;
            this.byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
            this.buffer = this.byteBuffer.asIntBuffer();
            this.buffer.clear().flip();
        }
        
        @Override
        public boolean hasNext() {
            if (!this.buffer.hasRemaining()) {
                this.byteBuffer.clear();
                try {
                    this.channel.read(this.byteBuffer);
                }
                catch (final IOException e) {
                    throw new RuntimeException(e);
                }
                this.byteBuffer.flip();
                this.buffer.clear();
                this.buffer.limit();
            }
            return this.buffer.hasRemaining();
        }
        
        @Override
        public int nextInt() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            return this.buffer.get();
        }
    }
    
    private static final class IntDataInputWrapper implements IntIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private int next;
        
        public IntDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readInt();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public int nextInt() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
    
    private static final class FloatDataNioInputWrapper implements FloatIterator
    {
        private final ReadableByteChannel channel;
        private final ByteBuffer byteBuffer;
        private final FloatBuffer buffer;
        
        public FloatDataNioInputWrapper(final ReadableByteChannel channel, final ByteOrder byteOrder) {
            this.channel = channel;
            this.byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
            this.buffer = this.byteBuffer.asFloatBuffer();
            this.buffer.clear().flip();
        }
        
        @Override
        public boolean hasNext() {
            if (!this.buffer.hasRemaining()) {
                this.byteBuffer.clear();
                try {
                    this.channel.read(this.byteBuffer);
                }
                catch (final IOException e) {
                    throw new RuntimeException(e);
                }
                this.byteBuffer.flip();
                this.buffer.clear();
                this.buffer.limit();
            }
            return this.buffer.hasRemaining();
        }
        
        @Override
        public float nextFloat() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            return this.buffer.get();
        }
    }
    
    private static final class FloatDataInputWrapper implements FloatIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private float next;
        
        public FloatDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readFloat();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public float nextFloat() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
    
    private static final class LongDataNioInputWrapper implements LongIterator
    {
        private final ReadableByteChannel channel;
        private final ByteBuffer byteBuffer;
        private final LongBuffer buffer;
        
        public LongDataNioInputWrapper(final ReadableByteChannel channel, final ByteOrder byteOrder) {
            this.channel = channel;
            this.byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
            this.buffer = this.byteBuffer.asLongBuffer();
            this.buffer.clear().flip();
        }
        
        @Override
        public boolean hasNext() {
            if (!this.buffer.hasRemaining()) {
                this.byteBuffer.clear();
                try {
                    this.channel.read(this.byteBuffer);
                }
                catch (final IOException e) {
                    throw new RuntimeException(e);
                }
                this.byteBuffer.flip();
                this.buffer.clear();
                this.buffer.limit();
            }
            return this.buffer.hasRemaining();
        }
        
        @Override
        public long nextLong() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            return this.buffer.get();
        }
    }
    
    private static final class LongDataInputWrapper implements LongIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private long next;
        
        public LongDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readLong();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public long nextLong() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
    
    private static final class DoubleDataNioInputWrapper implements DoubleIterator
    {
        private final ReadableByteChannel channel;
        private final ByteBuffer byteBuffer;
        private final DoubleBuffer buffer;
        
        public DoubleDataNioInputWrapper(final ReadableByteChannel channel, final ByteOrder byteOrder) {
            this.channel = channel;
            this.byteBuffer = ByteBuffer.allocateDirect(BinIO.BUFFER_SIZE).order(byteOrder);
            this.buffer = this.byteBuffer.asDoubleBuffer();
            this.buffer.clear().flip();
        }
        
        @Override
        public boolean hasNext() {
            if (!this.buffer.hasRemaining()) {
                this.byteBuffer.clear();
                try {
                    this.channel.read(this.byteBuffer);
                }
                catch (final IOException e) {
                    throw new RuntimeException(e);
                }
                this.byteBuffer.flip();
                this.buffer.clear();
                this.buffer.limit();
            }
            return this.buffer.hasRemaining();
        }
        
        @Override
        public double nextDouble() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            return this.buffer.get();
        }
    }
    
    private static final class DoubleDataInputWrapper implements DoubleIterator
    {
        private final DataInput dataInput;
        private boolean toAdvance;
        private boolean endOfProcess;
        private double next;
        
        public DoubleDataInputWrapper(final DataInput dataInput) {
            this.toAdvance = true;
            this.endOfProcess = false;
            this.dataInput = dataInput;
        }
        
        @Override
        public boolean hasNext() {
            if (!this.toAdvance) {
                return !this.endOfProcess;
            }
            this.toAdvance = false;
            try {
                this.next = this.dataInput.readDouble();
            }
            catch (final EOFException eof) {
                this.endOfProcess = true;
            }
            catch (final IOException rethrow) {
                throw new RuntimeException(rethrow);
            }
            return !this.endOfProcess;
        }
        
        @Override
        public double nextDouble() {
            if (!this.hasNext()) {
                throw new NoSuchElementException();
            }
            this.toAdvance = true;
            return this.next;
        }
    }
}
