* @param streamDictionary the dictionary that contains filter information
     * @param filterHandlers the map used to look up a handler for each type of filter
     * @return the decoded bytes
     * @throws IOException if there are any problems decoding the bytes
     * @since 5.0.4
     */
    public static byte[] decodeBytes(byte[] b, final PdfDictionary streamDictionary, Map<PdfName, FilterHandlers.FilterHandler> filterHandlers) throws IOException {
        PdfObject filter = getPdfObjectRelease(streamDictionary.get(PdfName.FILTER));

        ArrayList<PdfObject> filters = new ArrayList<PdfObject>();
        if (filter != null) {
            if (filter.isName())
                filters.add(filter);
            else if (filter.isArray())
                filters = ((PdfArray)filter).getArrayList();
        }
        ArrayList<PdfObject> dp = new ArrayList<PdfObject>();
        PdfObject dpo = getPdfObjectRelease(streamDictionary.get(PdfName.DECODEPARMS));
        if (dpo == null || !dpo.isDictionary() && !dpo.isArray())
            dpo = getPdfObjectRelease(streamDictionary.get(PdfName.DP));
        if (dpo != null) {
            if (dpo.isDictionary())
                dp.add(dpo);
            else if (dpo.isArray())
                dp = ((PdfArray)dpo).getArrayList();
        }
        for (int j = 0; j < filters.size(); ++j) {
            PdfName filterName = (PdfName)filters.get(j);
            FilterHandlers.FilterHandler filterHandler = filterHandlers.get(filterName);
            if (filterHandler == null)
                throw new UnsupportedPdfException(MessageLocalization.getComposedMessage("the.filter.1.is.not.supported", filterName));
            
            PdfDictionary decodeParams;
            if (j < dp.size()){
                PdfObject dpEntry = getPdfObject(dp.get(j));
                if (dpEntry instanceof PdfDictionary){
                    decodeParams = (PdfDictionary)dpEntry;
                } else if (dpEntry == null || dpEntry instanceof PdfNull) {
                    decodeParams = null;
                } else {
                    throw new UnsupportedPdfException(MessageLocalization.getComposedMessage("the.decode.parameter.type.1.is.not.supported", dpEntry.getClass().toString()));
                }
                
            } else {
                decodeParams = null;
            }
            b = filterHandler.decode(b, filterName, decodeParams, streamDictionary);
        }
        return b;
    }