public Map<COSObjectKey, COSBase> parseAllObjects() throws IOException
    {
        Map<COSObjectKey, COSBase> allObjects = new HashMap<>();
        try
        {
            Map<Integer, Long> objectNumbers = privateReadObjectOffsets();
            // count the number of object numbers eliminating double entries
            long numberOfObjNumbers = objectNumbers.values().stream().distinct().count();
            // the usage of the index should be restricted to cases where more than one
            // object use the same object number.
            // there are malformed pdfs in the wild which would lead to false results if
            // pdfbox always relies on the index if available. In most cases the object number
            // is sufficient to choose the correct object
            boolean indexNeeded = objectNumbers.size() > numberOfObjNumbers;
            long currentPosition = source.getPosition();
            if (firstObject > 0 && currentPosition < firstObject)
            {
                source.skip(firstObject - (int) currentPosition);
            }
            int index = 0;
            for (Entry<Integer, Long> entry : objectNumbers.entrySet())
            {
                COSObjectKey objectKey = getObjectKey(entry.getValue(), 0);
                // skip object if the index doesn't match
                if (indexNeeded && objectKey.getStreamIndex() > -1
                        && objectKey.getStreamIndex() != index)
                {
                    index++;
                    continue;
                }
                int finalPosition = firstObject + entry.getKey();
                currentPosition = source.getPosition();
                if (finalPosition > 0 && currentPosition < finalPosition)
                {
                    // jump to the offset of the object to be parsed
                    source.skip(finalPosition - (int) currentPosition);
                }
                COSBase streamObject = parseDirObject();
                if (streamObject != null)
                {
                    streamObject.setDirect(false);
                }
                allObjects.put(objectKey, streamObject);
                index++;
            }
        }
        finally
        {
            source.close();
            document = null;
        }
        return allObjects;
    }
@Test
    void testParseAllObjectsIndexed() throws IOException
    {
        COSStream stream = new COSStream();
        stream.setItem(COSName.N, COSInteger.THREE);
        stream.setItem(COSName.FIRST, COSInteger.get(13));
        OutputStream outputStream = stream.createOutputStream();
        // use object number 4 for two objects
        outputStream.write("6 0 4 5 4 11 true false true".getBytes());
        outputStream.close();
        COSDocument cosDoc = new COSDocument();
        Map<COSObjectKey, Long> xrefTable = cosDoc.getXrefTable();
        // select the second object from the stream for object number 4 by using 2 as value for the index
        xrefTable.put(new COSObjectKey(6, 0, 0), -1L);
        xrefTable.put(new COSObjectKey(4, 0, 2), -1L);
        PDFObjectStreamParser objectStreamParser = new PDFObjectStreamParser(stream, cosDoc);
        Map<COSObjectKey, COSBase> objectNumbers = objectStreamParser.parseAllObjects();
        assertEquals(2, objectNumbers.size());
        assertEquals(COSBoolean.TRUE, objectNumbers.get(new COSObjectKey(6, 0)));
        assertEquals(COSBoolean.TRUE, objectNumbers.get(new COSObjectKey(4, 0)));

        // select the first object from the stream for object number 4 by using 1 as value for the index
        // remove the old entry first to be sure it is replaced
        xrefTable.remove(new COSObjectKey(4, 0));
        xrefTable.put(new COSObjectKey(4, 0, 1), -1L);
        objectStreamParser = new PDFObjectStreamParser(stream, cosDoc);
        objectNumbers = objectStreamParser.parseAllObjects();
        assertEquals(2, objectNumbers.size());
        assertEquals(COSBoolean.TRUE, objectNumbers.get(new COSObjectKey(6, 0)));
        assertEquals(COSBoolean.FALSE, objectNumbers.get(new COSObjectKey(4, 0)));
    }