public CMap parse(RandomAccessRead randomAcccessRead) throws IOException
    {
        CMap result = new CMap();
        Object previousToken = null;
        Object token = parseNextToken(randomAcccessRead);
        while (token != null)
        {
            if (token instanceof Operator)
            {
                Operator op = (Operator) token;
                if (op.op.equals("endcmap"))
                {
                    // end of CMap reached, stop reading as there isn't any interesting info anymore
                    break;
                }

                if (op.op.equals("usecmap") && previousToken instanceof LiteralName)
                {
                    parseUsecmap((LiteralName) previousToken, result);
                }
                else if (previousToken instanceof Number)
                {
                    if (op.op.equals("begincodespacerange"))
                    {
                        parseBegincodespacerange((Number) previousToken, randomAcccessRead, result);
                    }
                    else if (op.op.equals("beginbfchar"))
                    {
                        parseBeginbfchar((Number) previousToken, randomAcccessRead, result);
                    }
                    else if (op.op.equals("beginbfrange"))
                    {
                        parseBeginbfrange((Number) previousToken, randomAcccessRead, result);
                    }
                    else if (op.op.equals("begincidchar"))
                    {
                        parseBegincidchar((Number) previousToken, randomAcccessRead, result);
                    }
                    else if (op.op.equals("begincidrange") && previousToken instanceof Integer)
                    {
                        parseBegincidrange((Integer) previousToken, randomAcccessRead, result);
                    }
                }
            }
            else if (token instanceof LiteralName)
            {
                parseLiteralName((LiteralName) token, randomAcccessRead, result);
            }
            previousToken = token;
            token = parseNextToken(randomAcccessRead);
        }
        return result;
    }
@Test
    void testLookup() throws IOException
    {
        final String resourceDir = "src/test/resources/cmap";
        File inDir = new File(resourceDir);

        CMap cMap = new CMapParser()
                .parse(new RandomAccessReadBufferedFile(new File(inDir, "CMapTest")));

        // char mappings
        byte[] bytes1 = {0, 1};
        assertEquals("A", cMap.toUnicode(bytes1), "bytes 00 01 from bfrange <0001> <0005> <0041>");

        byte[] bytes2 = {1, 00};
        String str2 = "0";
        assertEquals(str2,
                cMap.toUnicode(bytes2), "bytes 01 00 from bfrange <0100> <0109> <0030>");

        byte[] bytes3 = { 1, 32 };
        assertEquals("P", cMap.toUnicode(bytes3), "bytes 01 00 from bfrange <0100> <0109> <0030>");

        byte[] bytes4 = { 1, 33 };
        assertEquals("R", cMap.toUnicode(bytes4), "bytes 01 00 from bfrange <0100> <0109> <0030>");

        byte[] bytes5 = { 0, 10 };
        String str5 = "*";
        assertEquals(str5, cMap.toUnicode(bytes5), "bytes 00 0A from bfchar <000A> <002A>");

        byte[] bytes6 = { 1, 10 };
        String str6 = "+";
        assertEquals(str6, cMap.toUnicode(bytes6), "bytes 01 0A from bfchar <010A> <002B>");

        // CID mappings
        byte[] cid1 = { 0, 65 };
        assertEquals(65, cMap.toCID(cid1), "CID 65 from cidrange <0000> <00ff> 0 ");

        byte[] cid2 = { 1, 24 };
        int strCID2 = 0x0118;
        assertEquals(strCID2, cMap.toCID(cid2), "CID 280 from cidrange <0100> <01ff> 256");

        byte[] cid3 = { 2, 8 };
        int strCID3 = 0x0208;
        assertEquals(strCID3, cMap.toCID(cid3), "CID 520 from cidchar <0208> 520");

        byte[] cid4 = { 1, 0x2c };
        int strCID4 = 0x12C;
        assertEquals(strCID4, cMap.toCID(cid4), "CID 300 from cidrange <0300> <0300> 300");
    }