public static NanoPost getNanoPostFromBytes(byte[] data, boolean inbox) throws MalformedNanoPostException {
        try {
            if (data == null) {
                throw new MalformedNanoPostException("Not a nanopost");
            }
            
            // 1. Determine data size
            int dataLength = data.length;
            DataInputStream dis = new DataInputStream(new ByteArrayInputStream(data));

            if (dataLength < EncryptionProvider.SHA_256_HASH_SIZE_BYTES * 2) {
                throw new MalformedNanoPostException("Post data is too small");
            }

            // 2. Get post hash
            byte[] postHash = new byte[EncryptionProvider.SHA_256_HASH_SIZE_BYTES]; // SHA-256
            dis.readFully(postHash);

            // 3. Get hash of data and compare
            byte[] dataHashToCheck; // SHA-256

            // Whole nanopost data to check (including parent hash)
            byte[] npData = new byte[dataLength - EncryptionProvider.SHA_256_HASH_SIZE_BYTES];
            dis.readFully(npData);


            dataHashToCheck = EncryptionProvider.sha256(npData);

            boolean result = Arrays.equals(postHash, dataHashToCheck);
            if (!result) {
                System.err.println("[H] Hash from header: " + ByteUtils.bytesToHexString(postHash));
                System.err.println("[H] Real hash       : " + ByteUtils.bytesToHexString(dataHashToCheck));

                throw new MalformedNanoPostException("Post hash and real hash of data is not equals. Is post data corrupted?");
            }

            dis = new DataInputStream(new ByteArrayInputStream(npData));

            // 4. Get parent hash
            byte[] parentHash = new byte[EncryptionProvider.SHA_256_HASH_SIZE_BYTES];
            dis.readFully(parentHash, 0, EncryptionProvider.SHA_256_HASH_SIZE_BYTES);

            //System.out.println("[H] Post hash   : " + ByteUtils.bytesToHexString(postHash) + " | Parent hash: " + ByteUtils.bytesToHexString(parentHash));

            // 5. Read post data
            byte[] postData = new byte[dataLength - (2 * EncryptionProvider.SHA_256_HASH_SIZE_BYTES)];
            dis.readFully(postData);
            dis = new DataInputStream(new ByteArrayInputStream(postData));

            // 6. Read post JSON data
            String postJson = dis.readUTF();

            //System.out.println("[H] Post JSON : " + postJson);

            // 7. Read post attach data
            String attachFileName = dis.readUTF();

            NanoPostAttach att = null;

            if (!attachFileName.isEmpty()) {
                int attachSize = dis.readInt();
                if (attachSize <= 0) {
                    throw new MalformedNanoPostException("Attach size is less or equals ZERO.");
                }

                byte[] attachData = new byte[attachSize];
                dis.read(attachData);

                if (!inbox) {
                    att = new NanoPostAttach(attachData, attachFileName, new File(MainClass.NANOPOSTS_DIR + System.getProperty("file.separator") + ByteUtils.bytesToHexString(postHash) + "_" + attachFileName));
                } else {
                    att = new NanoPostAttach(attachData, attachFileName, new File(MainClass.OUTBOX_DIR + System.getProperty("file.separator") + ByteUtils.bytesToHexString(postHash) + "_" + attachFileName));
                }
            }

            NanoPost np = new NanoPost(postHash, parentHash, postJson, att);

            return np;
        } catch (IOException ex) {
            throw new MalformedNanoPostException("IO Error!");
        }
    }