/*
 * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.print;

import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.print.PrinterJob;
import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.ServiceUIFactory;
import javax.print.attribute.Attribute;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.AttributeSetUtilities;
import javax.print.attribute.EnumSyntax;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.PrintServiceAttribute;
import javax.print.attribute.PrintServiceAttributeSet;
import javax.print.attribute.HashPrintServiceAttributeSet;
import javax.print.attribute.standard.PrinterName;
import javax.print.attribute.standard.PrinterIsAcceptingJobs;
import javax.print.attribute.standard.QueuedJobCount;
import javax.print.attribute.standard.JobName;
import javax.print.attribute.standard.RequestingUserName;
import javax.print.attribute.standard.Chromaticity;
import javax.print.attribute.standard.Copies;
import javax.print.attribute.standard.CopiesSupported;
import javax.print.attribute.standard.Destination;
import javax.print.attribute.standard.DialogOwner;
import javax.print.attribute.standard.DialogTypeSelection;
import javax.print.attribute.standard.Fidelity;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.OrientationRequested;
import javax.print.attribute.standard.PageRanges;
import javax.print.attribute.standard.PrinterState;
import javax.print.attribute.standard.PrinterStateReason;
import javax.print.attribute.standard.PrinterStateReasons;
import javax.print.attribute.standard.Severity;
import javax.print.attribute.standard.Sides;
import javax.print.attribute.standard.ColorSupported;
import javax.print.attribute.standard.PrintQuality;
import javax.print.attribute.standard.PrinterResolution;
import javax.print.attribute.standard.SheetCollate;
import javax.print.event.PrintServiceAttributeListener;
import sun.awt.windows.WPrinterJob;

public final class Win32PrintService implements PrintService, AttributeUpdater,
                                          SunPrinterJobService {

    public static MediaSize[] predefMedia = Win32MediaSize.getPredefMedia();

    private static final DocFlavor[] supportedFlavors = {
        DocFlavor.BYTE_ARRAY.GIF,
        DocFlavor.INPUT_STREAM.GIF,
        DocFlavor.URL.GIF,
        DocFlavor.BYTE_ARRAY.JPEG,
        DocFlavor.INPUT_STREAM.JPEG,
        DocFlavor.URL.JPEG,
        DocFlavor.BYTE_ARRAY.PNG,
        DocFlavor.INPUT_STREAM.PNG,
        DocFlavor.URL.PNG,
        DocFlavor.SERVICE_FORMATTED.PAGEABLE,
        DocFlavor.SERVICE_FORMATTED.PRINTABLE,
        DocFlavor.BYTE_ARRAY.AUTOSENSE,
        DocFlavor.URL.AUTOSENSE,
        DocFlavor.INPUT_STREAM.AUTOSENSE
    };

    /* let's try to support a few of these */
    private static final Class<?>[] serviceAttrCats = {
        PrinterName.class,
        PrinterIsAcceptingJobs.class,
        QueuedJobCount.class,
        ColorSupported.class,
    };

    /*  it turns out to be inconvenient to store the other categories
     *  separately because many attributes are in multiple categories.
     */
    private static Class<?>[] otherAttrCats = {
        JobName.class,
        RequestingUserName.class,
        Copies.class,
        Destination.class,
        OrientationRequested.class,
        PageRanges.class,
        Media.class,
        MediaPrintableArea.class,
        Fidelity.class,
        // We support collation on 2D printer jobs, even if the driver can't.
        SheetCollate.class,
        SunAlternateMedia.class,
        Chromaticity.class
    };


    /*
     * This table together with methods findWin32Media and
     * findMatchingMediaSizeNameMM are declared public as these are also
     * used in WPrinterJob.java.
     */
    public static final MediaSizeName[] dmPaperToPrintService = {
      MediaSizeName.NA_LETTER, MediaSizeName.NA_LETTER,
      MediaSizeName.TABLOID, MediaSizeName.LEDGER,
      MediaSizeName.NA_LEGAL, MediaSizeName.INVOICE,
      MediaSizeName.EXECUTIVE, MediaSizeName.ISO_A3,
      MediaSizeName.ISO_A4, MediaSizeName.ISO_A4,
      MediaSizeName.ISO_A5, MediaSizeName.JIS_B4,
      MediaSizeName.JIS_B5, MediaSizeName.FOLIO,
      MediaSizeName.QUARTO, MediaSizeName.NA_10X14_ENVELOPE,
      MediaSizeName.B, MediaSizeName.NA_LETTER,
      MediaSizeName.NA_NUMBER_9_ENVELOPE, MediaSizeName.NA_NUMBER_10_ENVELOPE,
      MediaSizeName.NA_NUMBER_11_ENVELOPE, MediaSizeName.NA_NUMBER_12_ENVELOPE,
      MediaSizeName.NA_NUMBER_14_ENVELOPE, MediaSizeName.C,
      MediaSizeName.D, MediaSizeName.E,
      MediaSizeName.ISO_DESIGNATED_LONG, MediaSizeName.ISO_C5,
      MediaSizeName.ISO_C3, MediaSizeName.ISO_C4,
      MediaSizeName.ISO_C6, MediaSizeName.ITALY_ENVELOPE,
      MediaSizeName.ISO_B4, MediaSizeName.ISO_B5,
      MediaSizeName.ISO_B6, MediaSizeName.ITALY_ENVELOPE,
      MediaSizeName.MONARCH_ENVELOPE, MediaSizeName.PERSONAL_ENVELOPE,
      MediaSizeName.NA_10X15_ENVELOPE, MediaSizeName.NA_9X12_ENVELOPE,
      MediaSizeName.FOLIO, MediaSizeName.ISO_B4,
      MediaSizeName.JAPANESE_POSTCARD, MediaSizeName.NA_9X11_ENVELOPE,
    };

    private static final MediaTray[] dmPaperBinToPrintService = {
      MediaTray.TOP, MediaTray.BOTTOM, MediaTray.MIDDLE,
      MediaTray.MANUAL, MediaTray.ENVELOPE, Win32MediaTray.ENVELOPE_MANUAL,
      Win32MediaTray.AUTO, Win32MediaTray.TRACTOR,
      Win32MediaTray.SMALL_FORMAT, Win32MediaTray.LARGE_FORMAT,
      MediaTray.LARGE_CAPACITY, null, null,
      MediaTray.MAIN, Win32MediaTray.FORMSOURCE,
    };

    // from wingdi.h
    private static int DM_PAPERSIZE = 0x2;
    private static int DM_PRINTQUALITY = 0x400;
    private static int DM_YRESOLUTION = 0x2000;
    private static final int DMRES_MEDIUM = -3;
    private static final int DMRES_HIGH = -4;
    private static final int DMORIENT_LANDSCAPE = 2;
    private static final int DMDUP_VERTICAL = 2;
    private static final int DMDUP_HORIZONTAL = 3;
    private static final int DMCOLLATE_TRUE = 1;
    private static final int DMCOLOR_MONOCHROME = 1;
    private static final int DMCOLOR_COLOR = 2;


    // media sizes with indices above dmPaperToPrintService' length
    private static final int DMPAPER_A2 = 66;
    private static final int DMPAPER_A6 = 70;
    private static final int DMPAPER_B6_JIS = 88;


    // Bit settings for getPrinterCapabilities which matches that
    // of native getCapabilities in WPrinterJob.cpp
    private static final int DEVCAP_COLOR = 0x0001;
    private static final int DEVCAP_DUPLEX = 0x0002;
    private static final int DEVCAP_COLLATE = 0x0004;
    private static final int DEVCAP_QUALITY = 0x0008;
    private static final int DEVCAP_POSTSCRIPT = 0x0010;

    private String printer;
    private PrinterName name;
    private String port;

    private transient PrintServiceAttributeSet lastSet;
    private transient ServiceNotifier notifier = null;

    private MediaSizeName[] mediaSizeNames;
    private MediaPrintableArea[] mediaPrintables;
    private MediaTray[] mediaTrays;
    private PrinterResolution[] printRes;
    private HashMap<MediaSizeName, MediaPrintableArea> mpaMap;
    private int nCopies;
    private int prnCaps;
    private int[] defaultSettings;

    private boolean gotTrays;
    private boolean gotCopies;
    private boolean mediaInitialized;
    private boolean mpaListInitialized;

    private ArrayList<Integer> idList;
    private MediaSize[] mediaSizes;

    private boolean isInvalid;

    Win32PrintService(String name) {
        if (name == null) {
            throw new IllegalArgumentException("null printer name");
        }
        printer = name;

        // initialize flags
        mediaInitialized = false;
        gotTrays = false;
        gotCopies = false;
        isInvalid = false;
        printRes = null;
        prnCaps = 0;
        defaultSettings = null;
        port = null;
    }

    public void invalidateService() {
        isInvalid = true;
    }

    @Override
    public String getName() {
        return printer;
    }

    private PrinterName getPrinterName() {
        if (name == null) {
            name = new PrinterName(printer, null);
        }
        return name;
    }

    public int findPaperID(MediaSizeName msn) {
        if (msn instanceof Win32MediaSize) {
            Win32MediaSize winMedia = (Win32MediaSize)msn;
            return winMedia.getDMPaper();
        } else {
            for (int id=0; id<dmPaperToPrintService.length;id++) {
                if (dmPaperToPrintService[id].equals(msn)) {
                    return id+1; // DMPAPER_LETTER == 1
                }
            }
            if (msn.equals(MediaSizeName.ISO_A2)) {
                return DMPAPER_A2;
            }
            else if (msn.equals(MediaSizeName.ISO_A6)) {
                return DMPAPER_A6;
            }
            else if (msn.equals(MediaSizeName.JIS_B6)) {
                return DMPAPER_B6_JIS;
            }
        }

        // If not found in predefined Windows ID, then we search through
        // the returned IDs of the driver because they can define their own
        // unique IDs.
        initMedia();

        if ((idList != null) && (mediaSizes != null) &&
            (idList.size() == mediaSizes.length)) {
            for (int i=0; i< idList.size(); i++) {
                if (mediaSizes[i].getMediaSizeName() == msn) {
                    return idList.get(i).intValue();
                }
            }
        }
        return 0;
    }

    public int findTrayID(MediaTray tray) {

        getMediaTrays(); // make sure they are initialised.

        if (tray instanceof Win32MediaTray) {
            Win32MediaTray winTray = (Win32MediaTray)tray;
            return winTray.getDMBinID();
        }
        for (int id=0; id<dmPaperBinToPrintService.length; id++) {
            if (tray.equals(dmPaperBinToPrintService[id])) {
                return id+1; // DMBIN_FIRST = 1;
            }
        }
        return 0; // didn't find the tray
    }

    public MediaTray findMediaTray(int dmBin) {
        if (dmBin >= 1 && dmBin <= dmPaperBinToPrintService.length) {
            return dmPaperBinToPrintService[dmBin-1];
        }
        MediaTray[] trays = getMediaTrays();
        if (trays != null) {
            for (int i=0;i<trays.length;i++) {
                if(trays[i] instanceof Win32MediaTray) {
                    Win32MediaTray win32Tray = (Win32MediaTray)trays[i];
                    if (win32Tray.winID == dmBin) {
                        return win32Tray;
                    }
                }
            }
        }
        return Win32MediaTray.AUTO;
    }

    public MediaSizeName findWin32Media(int dmIndex) {
        if (dmIndex >= 1 && dmIndex <= dmPaperToPrintService.length) {
            return dmPaperToPrintService[dmIndex - 1];
        }
        switch(dmIndex) {
            /* matching media sizes with indices beyond
               dmPaperToPrintService's length */
            case DMPAPER_A2:
                return MediaSizeName.ISO_A2;
            case DMPAPER_A6:
                return MediaSizeName.ISO_A6;
            case DMPAPER_B6_JIS:
                return MediaSizeName.JIS_B6;
            default:
                return null;
        }
    }

    private boolean addToUniqueList(ArrayList<MediaSizeName> msnList,
                                    MediaSizeName mediaName) {
        MediaSizeName msn;
        for (int i=0; i< msnList.size(); i++) {
            msn = msnList.get(i);
            if (msn == mediaName) {
                return false;
            }
        }
        msnList.add(mediaName);
        return true;
    }

    private synchronized void initMedia() {
        if (mediaInitialized == true) {
            return;
        }
        mediaInitialized = true;
        int[] media = getAllMediaIDs(printer, getPort());
        if (media == null) {
            return;
        }

        ArrayList<MediaSizeName> msnList = new ArrayList<>();
        ArrayList<Win32MediaSize> trailingWmsList = new ArrayList<Win32MediaSize>();
        MediaSizeName mediaName;
        boolean added;
        boolean queryFailure = false;
        float[] prnArea;

        // Get all mediaSizes supported by the printer.
        // We convert media to ArrayList idList and pass this to the
        // function for getting mediaSizes.
        // This is to ensure that mediaSizes and media IDs have 1-1 correspondence.
        // We remove from ID list any invalid mediaSize.  Though this is rare,
        // it happens in HP 4050 German driver.

        idList = new ArrayList<>();
        for (int i=0; i < media.length; i++) {
            idList.add(Integer.valueOf(media[i]));
        }

        ArrayList<String> dmPaperNameList = new ArrayList<String>();
        mediaSizes = getMediaSizes(idList, media, dmPaperNameList);
        for (int i = 0; i < idList.size(); i++) {

            // match Win ID with our predefined ID using table
            mediaName = findWin32Media(idList.get(i).intValue());
            // Verify that this standard size is the same size as that
            // reported by the driver. This should be the case except when
            // the driver is mis-using a standard windows paper ID.
            if (mediaName != null &&
                idList.size() == mediaSizes.length) {
                MediaSize win32Size = MediaSize.getMediaSizeForName(mediaName);
                MediaSize driverSize = mediaSizes[i];
                int error = 2540; // == 1/10"
                if (Math.abs(win32Size.getX(1)-driverSize.getX(1)) > error ||
                    Math.abs(win32Size.getY(1)-driverSize.getY(1)) > error)
                {
                   mediaName = null;
                }
            }
            boolean dmPaperIDMatched = (mediaName != null);

            // No match found, then we get the MediaSizeName out of the MediaSize
            // This requires 1-1 correspondence, lengths must be checked.
            if ((mediaName == null) && (idList.size() == mediaSizes.length)) {
                mediaName = mediaSizes[i].getMediaSizeName();
            }

            // Add mediaName to the msnList
            added = false;
            if (mediaName != null) {
                added = addToUniqueList(msnList, mediaName);
            }
            if ((!dmPaperIDMatched || !added) && (idList.size() == dmPaperNameList.size())) {
                /* The following block allows to add such media names to the list, whose sizes
                 * matched with media sizes predefined in JDK, while whose paper IDs did not,
                 * or whose sizes and paper IDs both did not match with any predefined in JDK.
                 */
                Win32MediaSize wms = Win32MediaSize.findMediaName(dmPaperNameList.get(i));
                if ((wms == null) && (idList.size() == mediaSizes.length)) {
                    wms = new Win32MediaSize(dmPaperNameList.get(i), idList.get(i));
                    mediaSizes[i] = new MediaSize(mediaSizes[i].getX(MediaSize.MM),
                        mediaSizes[i].getY(MediaSize.MM), MediaSize.MM, wms);
                }
                if ((wms != null) && (wms != mediaName)) {
                    if (!added) {
                        added = addToUniqueList(msnList, mediaName = wms);
                    } else {
                        trailingWmsList.add(wms);
                    }
                }
            }
        }
        for (Win32MediaSize wms : trailingWmsList) {
            added = addToUniqueList(msnList, wms);
        }

        // init mediaSizeNames
        mediaSizeNames = new MediaSizeName[msnList.size()];
        msnList.toArray(mediaSizeNames);
    }


    /*
     * Gets a list of MediaPrintableAreas using a call to native function.
     *  msn is MediaSizeName used to get a specific printable area.  If null,
     *  it will get all the supported MediPrintableAreas.
     */
    private synchronized MediaPrintableArea[] getMediaPrintables(MediaSizeName msn)
    {
        if (msn == null)  {
            if (mpaListInitialized == true) {
                return mediaPrintables;
            }
        } else {
            // get from cached mapping of MPAs
            if (mpaMap != null && (mpaMap.get(msn) != null)) {
                MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];
                mpaArr[0] = mpaMap.get(msn);
                return mpaArr;
            }
        }

        initMedia();

        if ((mediaSizeNames == null) || (mediaSizeNames.length == 0)) {
            return null;
        }

        MediaSizeName[] loopNames;
        if (msn != null) {
            loopNames = new MediaSizeName[1];
            loopNames[0] = msn;
        } else {
            loopNames = mediaSizeNames;
        }

        if (mpaMap == null) {
            mpaMap = new HashMap<>();
        }

        for (int i=0; i < loopNames.length; i++) {
            MediaSizeName mediaName = loopNames[i];

            if (mpaMap.get(mediaName) != null) {
                continue;
             }

            if (mediaName != null) {
                int defPaper = findPaperID(mediaName);
                float[] prnArea = (defPaper != 0) ? getMediaPrintableArea(printer, defPaper) : null;
                MediaPrintableArea printableArea = null;
                if (prnArea != null) {
                    try {
                        printableArea = new MediaPrintableArea(prnArea[0],
                                                               prnArea[1],
                                                               prnArea[2],
                                                               prnArea[3],
                                                 MediaPrintableArea.INCH);

                        mpaMap.put(mediaName, printableArea);
                    }
                    catch (IllegalArgumentException e) {
                    }
                } else {
                    // if getting  MPA failed, we use MediaSize
                    MediaSize ms = MediaSize.getMediaSizeForName(mediaName);

                    if (ms != null) {
                        try {
                            printableArea = new MediaPrintableArea(0, 0,
                                                     ms.getX(MediaSize.INCH),
                                                     ms.getY(MediaSize.INCH),
                                                     MediaPrintableArea.INCH);
                            mpaMap.put(mediaName, printableArea);
                        } catch (IllegalArgumentException e) {
                        }
                    }
                }
            } //mediaName != null
        }

       if (mpaMap.size() == 0) {
           return null;
       }

       if (msn != null) {
           if (mpaMap.get(msn) == null) {
               return null;
           }
           MediaPrintableArea[] mpaArr = new MediaPrintableArea[1];
           // by this time, we've already gotten the desired MPA
           mpaArr[0] = mpaMap.get(msn);
           return mpaArr;
       } else {
           mediaPrintables = mpaMap.values().toArray(new MediaPrintableArea[0]);
           mpaListInitialized = true;
           return mediaPrintables;
       }
    }


    private synchronized MediaTray[] getMediaTrays() {
        if (gotTrays == true && mediaTrays != null) {
            return mediaTrays;
        }
        String prnPort = getPort();
        int[] mediaTr = getAllMediaTrays(printer, prnPort);
        String[] winMediaTrayNames = getAllMediaTrayNames(printer, prnPort);

        if ((mediaTr == null) || (winMediaTrayNames == null)){
            return null;
        }

        /* first count how many valid bins there are so we can allocate
         * an array of the correct size
         */
        int nTray = 0;
        for (int i=0; i < mediaTr.length ; i++) {
            if (mediaTr[i] > 0) nTray++;
        }

        MediaTray[] arr = new MediaTray[nTray];
        int dmBin;

        /* Some drivers in Win 7 don't have the same length for DC_BINS and
         * DC_BINNAMES so there is no guarantee that lengths of mediaTr and
         * winMediaTrayNames are equal. To avoid getting ArrayIndexOutOfBounds,
         * we need to make sure we get the minimum of the two.
         */

        for (int i = 0, j=0; i < Math.min(mediaTr.length, winMediaTrayNames.length); i++) {
            dmBin = mediaTr[i];
            if (dmBin > 0) {
                // check for unsupported DMBINs and create new Win32MediaTray
                if ((dmBin > dmPaperBinToPrintService.length)
                    || (dmPaperBinToPrintService[dmBin-1] == null)) {
                    arr[j++] = new Win32MediaTray(dmBin, winMediaTrayNames[i]);
                } else {
                    arr[j++] = dmPaperBinToPrintService[dmBin-1];
                }
            }
            // no else - For invalid ids, just ignore it because assigning a "default"
            // value may result in duplicate trays.
        }
        mediaTrays = arr;
        gotTrays = true;
        return mediaTrays;
    }

    private boolean isSameSize(float w1, float h1, float w2, float h2) {
        float diffX = w1 - w2;
        float diffY = h1 - h2;
        // Get diff of reverse dimensions
        // EPSON Stylus COLOR 860 reverses envelope's width & height
        float diffXrev = w1 - h2;
        float diffYrev = h1 - w2;

        if (((Math.abs(diffX)<=1) && (Math.abs(diffY)<=1)) ||
            ((Math.abs(diffXrev)<=1) && (Math.abs(diffYrev)<=1))){
          return true;
        } else {
          return false;
        }
    }

    public MediaSizeName findMatchingMediaSizeNameMM (float w, float h){
        if (predefMedia != null) {
            for (int k=0; k<predefMedia.length;k++) {
                if (predefMedia[k] == null) {
                    continue;
                }

                if (isSameSize(predefMedia[k].getX(MediaSize.MM),
                               predefMedia[k].getY(MediaSize.MM),
                               w, h)) {
                  return predefMedia[k].getMediaSizeName();
                }
            }
        }
        return null;
    }


    private MediaSize[] getMediaSizes(ArrayList<Integer> idList, int[] media,
                                      ArrayList<String> dmPaperNameList) {
        if (dmPaperNameList == null) {
            dmPaperNameList = new ArrayList<String>();
        }

        String prnPort = getPort();
        int[] mediaSz = getAllMediaSizes(printer, prnPort);
        String[] winMediaNames = getAllMediaNames(printer, prnPort);
        MediaSizeName msn = null;
        MediaSize ms = null;
        float wid, ht;

        if ((mediaSz == null) || (winMediaNames == null)) {
            return null;
        }

        int nMedia = mediaSz.length/2;
        ArrayList<MediaSize> msList = new ArrayList<>();

        for (int i = 0; i < nMedia; i++, ms=null) {
            wid = mediaSz[i*2]/10f;
            ht = mediaSz[i*2+1]/10f;

            // Make sure to validate wid & ht.
            // HP LJ 4050 (german) causes IAE in Sonderformat paper, wid & ht
            // returned is not constant.
            if ((wid <= 0) || (ht <= 0)) {
                //Remove corresponding ID from list
                if (nMedia == media.length) {
                    Integer remObj = Integer.valueOf(media[i]);
                    idList.remove(idList.indexOf(remObj));
                }
                continue;
            }
            // Find matching media using dimensions.
            // This call matches only with our own predefined sizes.
            msn = findMatchingMediaSizeNameMM(wid, ht);
            if (msn != null) {
                ms = MediaSize.getMediaSizeForName(msn);
            }

            if (ms != null) {
                msList.add(ms);
                dmPaperNameList.add(winMediaNames[i]);
            } else {
                Win32MediaSize wms = Win32MediaSize.findMediaName(winMediaNames[i]);
                if (wms == null) {
                    wms = new Win32MediaSize(winMediaNames[i], media[i]);
                }
                try {
                    ms = new MediaSize(wid, ht, MediaSize.MM, wms);
                    msList.add(ms);
                    dmPaperNameList.add(winMediaNames[i]);
                } catch(IllegalArgumentException e) {
                    if (nMedia == media.length) {
                        Integer remObj = Integer.valueOf(media[i]);
                        idList.remove(idList.indexOf(remObj));
                    }
                }
            }
        }

        MediaSize[] arr2 = new MediaSize[msList.size()];
        msList.toArray(arr2);

        return arr2;
    }

    private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() {
        if (getJobStatus(printer, 2) != 1) {
            return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS;
        }
        else {
            return PrinterIsAcceptingJobs.ACCEPTING_JOBS;
        }
    }

    private PrinterState getPrinterState() {
        if (isInvalid) {
            return PrinterState.STOPPED;
        } else {
            return null;
        }
    }

    private PrinterStateReasons getPrinterStateReasons() {
        if (isInvalid) {
            PrinterStateReasons psr = new PrinterStateReasons();
            psr.put(PrinterStateReason.SHUTDOWN, Severity.ERROR);
            return psr;
        } else {
            return null;
        }
    }

    private QueuedJobCount getQueuedJobCount() {

        int count = getJobStatus(printer, 1);
        if (count != -1) {
            return new QueuedJobCount(count);
        }
        else {
            return new QueuedJobCount(0);
        }
    }

    private boolean isSupportedCopies(Copies copies) {
        synchronized (this) {
            if (gotCopies == false) {
                nCopies = getCopiesSupported(printer, getPort());
                gotCopies = true;
            }
        }
        int numCopies = copies.getValue();
        return (numCopies > 0 && numCopies <= nCopies);
    }

    private boolean isSupportedMedia(MediaSizeName msn) {

        initMedia();

        if (mediaSizeNames != null) {
            for (int i=0; i<mediaSizeNames.length; i++) {
                if (msn.equals(mediaSizeNames[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSupportedMediaPrintableArea(MediaPrintableArea mpa) {

        getMediaPrintables(null);
        int units = MediaPrintableArea.INCH;

        if (mediaPrintables != null) {
            for (int i=0; i<mediaPrintables.length; i++) {
                if ((mpa.getX(units) >= mediaPrintables[i].getX(units)) &&
                    (mpa.getY(units) >= mediaPrintables[i].getY(units)) &&
                    (mpa.getX(units) + mpa.getWidth(units) <=
                            mediaPrintables[i].getX(units) +
                            mediaPrintables[i].getWidth(units)) &&
                    (mpa.getY(units) + mpa.getHeight(units) <=
                            mediaPrintables[i].getY(units) +
                            mediaPrintables[i].getHeight(units))) {
                    return true;
                }
            }
        }
        return false;
    }

    private boolean isSupportedMediaTray(MediaTray msn) {
        MediaTray[] trays = getMediaTrays();

        if (trays != null) {
            for (int i=0; i<trays.length; i++) {
                if (msn.equals(trays[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    private int getPrinterCapabilities() {
        if (prnCaps == 0) {
            prnCaps = getCapabilities(printer, getPort());
        }
        return prnCaps;
    }

    private String getPort() {
        if (port == null) {
            port = getPrinterPort(printer);
        }
        return port;
    }

   /*
    * NOTE: defaults indices must match those in WPrinterJob.cpp
    */
    private int[] getDefaultPrinterSettings() {
        if (defaultSettings == null) {
            defaultSettings = getDefaultSettings(printer, getPort());
        }
        return defaultSettings;
    }

    private PrinterResolution[] getPrintResolutions() {
        if (printRes == null) {
            int[] prnRes = getAllResolutions(printer, getPort());
            if (prnRes == null) {
                printRes = new PrinterResolution[0];
            } else {
                int nRes = prnRes.length/2;

                ArrayList<PrinterResolution> arrList = new ArrayList<>();
                PrinterResolution pr;

                for (int i=0; i<nRes; i++) {
                  try {
                        pr = new PrinterResolution(prnRes[i*2],
                                       prnRes[i*2+1], PrinterResolution.DPI);
                        arrList.add(pr);
                    } catch (IllegalArgumentException e) {
                    }
                }

                printRes = arrList.toArray(new PrinterResolution[arrList.size()]);
            }
        }
        return printRes;
    }

    private boolean isSupportedResolution(PrinterResolution res) {
        PrinterResolution[] supportedRes = getPrintResolutions();
        if (supportedRes != null) {
            for (int i=0; i<supportedRes.length; i++) {
                if (res.equals(supportedRes[i])) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public DocPrintJob createPrintJob() {
        return new Win32PrintJob(this);
    }

    private PrintServiceAttributeSet getDynamicAttributes() {
        PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet();
        attrs.add(getPrinterIsAcceptingJobs());
        attrs.add(getQueuedJobCount());
        return attrs;
    }

    @Override
    public PrintServiceAttributeSet getUpdatedAttributes() {
        PrintServiceAttributeSet currSet = getDynamicAttributes();
        if (lastSet == null) {
            lastSet = currSet;
            return AttributeSetUtilities.unmodifiableView(currSet);
        } else {
            PrintServiceAttributeSet updates =
                new HashPrintServiceAttributeSet();
            Attribute []attrs =  currSet.toArray();
            for (int i=0; i<attrs.length; i++) {
                Attribute attr = attrs[i];
                if (!lastSet.containsValue(attr)) {
                    updates.add(attr);
                }
            }
            lastSet = currSet;
            return AttributeSetUtilities.unmodifiableView(updates);
        }
    }

    public void wakeNotifier() {
        synchronized (this) {
            if (notifier != null) {
                notifier.wake();
            }
        }
    }

    @Override
    public void addPrintServiceAttributeListener(PrintServiceAttributeListener
                                                 listener) {
        synchronized (this) {
            if (listener == null) {
                return;
            }
            if (notifier == null) {
                notifier = new ServiceNotifier(this);
            }
            notifier.addListener(listener);
        }
    }

    @Override
    public void removePrintServiceAttributeListener(
                                      PrintServiceAttributeListener listener) {
        synchronized (this) {
            if (listener == null || notifier == null ) {
                return;
            }
            notifier.removeListener(listener);
            if (notifier.isEmpty()) {
                notifier.stopNotifier();
                notifier = null;
            }
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public <T extends PrintServiceAttribute> T
        getAttribute(Class<T> category)
    {
        if (category == null) {
            throw new NullPointerException("category");
        }
        if (!(PrintServiceAttribute.class.isAssignableFrom(category))) {
            throw new IllegalArgumentException("Not a PrintServiceAttribute");
        }
        if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return (T)ColorSupported.SUPPORTED;
            } else {
                return (T)ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == PrinterName.class) {
            return (T)getPrinterName();
        } else if (category == PrinterState.class) {
            return (T)getPrinterState();
        } else if (category == PrinterStateReasons.class) {
            return (T)getPrinterStateReasons();
        } else if (category == QueuedJobCount.class) {
            return (T)getQueuedJobCount();
        } else if (category == PrinterIsAcceptingJobs.class) {
            return (T)getPrinterIsAcceptingJobs();
        } else {
            return null;
        }
    }

    @Override
    public PrintServiceAttributeSet getAttributes() {

        PrintServiceAttributeSet attrs = new  HashPrintServiceAttributeSet();
        attrs.add(getPrinterName());
        attrs.add(getPrinterIsAcceptingJobs());
        PrinterState prnState = getPrinterState();
        if (prnState != null) {
            attrs.add(prnState);
        }
        PrinterStateReasons prnStateReasons = getPrinterStateReasons();
        if (prnStateReasons != null) {
            attrs.add(prnStateReasons);
        }
        attrs.add(getQueuedJobCount());
        int caps = getPrinterCapabilities();
        if ((caps & DEVCAP_COLOR) != 0) {
            attrs.add(ColorSupported.SUPPORTED);
        } else {
            attrs.add(ColorSupported.NOT_SUPPORTED);
        }

        return AttributeSetUtilities.unmodifiableView(attrs);
    }

    @Override
    public DocFlavor[] getSupportedDocFlavors() {
        int len = supportedFlavors.length;
        DocFlavor[] supportedDocFlavors;
        int caps = getPrinterCapabilities();
        // doc flavors supported
        // if PostScript is supported
        if ((caps & DEVCAP_POSTSCRIPT) != 0) {
            supportedDocFlavors = new DocFlavor[len+3];
            System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
            supportedDocFlavors[len] = DocFlavor.BYTE_ARRAY.POSTSCRIPT;
            supportedDocFlavors[len+1] = DocFlavor.INPUT_STREAM.POSTSCRIPT;
            supportedDocFlavors[len+2] = DocFlavor.URL.POSTSCRIPT;
        } else {
            supportedDocFlavors = new DocFlavor[len];
            System.arraycopy(supportedFlavors, 0, supportedDocFlavors, 0, len);
        }
        return supportedDocFlavors;
    }

    @Override
    public boolean isDocFlavorSupported(DocFlavor flavor) {
        /* To avoid a native query which may be time-consuming
         * do not invoke native unless postscript support is being queried.
         * Instead just check the ones we 'always' support
         */
        DocFlavor[] supportedDocFlavors;
        if (isPostScriptFlavor(flavor)) {
            supportedDocFlavors = getSupportedDocFlavors();
        } else {
            supportedDocFlavors = supportedFlavors;
        }
        for (int f=0; f<supportedDocFlavors.length; f++) {
            if (flavor.equals(supportedDocFlavors[f])) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Class<?>[] getSupportedAttributeCategories() {
        ArrayList<Class<?>> categList = new ArrayList<>(otherAttrCats.length+3);
        for (int i=0; i < otherAttrCats.length; i++) {
            categList.add(otherAttrCats[i]);
        }

        int caps = getPrinterCapabilities();

        if ((caps & DEVCAP_DUPLEX) != 0) {
            categList.add(Sides.class);
        }

        if ((caps & DEVCAP_QUALITY) != 0) {
            int[] defaults = getDefaultPrinterSettings();
            // Added check: if supported, we should be able to get the default.
            if ((defaults[3] >= DMRES_HIGH) && (defaults[3] < 0)) {
                categList.add(PrintQuality.class);
            }
        }

        PrinterResolution[] supportedRes = getPrintResolutions();
        if ((supportedRes!=null) && (supportedRes.length>0)) {
            categList.add(PrinterResolution.class);
        }

        if (GraphicsEnvironment.isHeadless() == false) {
            categList.add(DialogOwner.class);
            categList.add(DialogTypeSelection.class);
        }
        return categList.toArray(new Class<?>[categList.size()]);
    }

    @Override
    public boolean
        isAttributeCategorySupported(Class<? extends Attribute> category)
    {

        if (category == null) {
            throw new NullPointerException("null category");
        }

        if (!(Attribute.class.isAssignableFrom(category))) {
            throw new IllegalArgumentException(category +
                                               " is not an Attribute");
        }

        Class<?>[] classList = getSupportedAttributeCategories();
        for (int i = 0; i < classList.length; i++) {
            if (category.equals(classList[i])) {
                return true;
            }
        }

        return false;
    }

    @Override
    public Object
        getDefaultAttributeValue(Class<? extends Attribute> category)
    {
        if (category == null) {
            throw new NullPointerException("null category");
        }
        if (!Attribute.class.isAssignableFrom(category)) {
            throw new IllegalArgumentException(category +
                                               " is not an Attribute");
        }

        if (!isAttributeCategorySupported(category)) {
            return null;
        }

        int[] defaults = getDefaultPrinterSettings();
        // indices must match those in WPrinterJob.cpp
        int defPaper = defaults[0];
        int defYRes = defaults[2];
        int defQuality = defaults[3];
        int defCopies = defaults[4];
        int defOrient = defaults[5];
        int defSides = defaults[6];
        int defCollate = defaults[7];
        int defColor = defaults[8];

        if (category == Copies.class) {
            if (defCopies > 0) {
                return new Copies(defCopies);
            } else {
                return new Copies(1);
            }
        } else if (category == Chromaticity.class) {
            if (defColor == DMCOLOR_COLOR) {
                return Chromaticity.COLOR;
            } else {
                return Chromaticity.MONOCHROME;
            }
        } else if (category == JobName.class) {
            return new JobName("Java Printing", null);
        } else if (category == OrientationRequested.class) {
            if (defOrient == DMORIENT_LANDSCAPE) {
                return OrientationRequested.LANDSCAPE;
            } else {
                return OrientationRequested.PORTRAIT;
            }
        } else if (category == PageRanges.class) {
            return new PageRanges(1, Integer.MAX_VALUE);
        } else if (category == Media.class) {
            MediaSizeName msn = findWin32Media(defPaper);
            if (msn != null) {
                if (!isSupportedMedia(msn) && mediaSizeNames != null) {
                    msn = mediaSizeNames[0];
                    defPaper = findPaperID(msn);
                }
                return msn;
             } else {
                 initMedia();
                 if ((mediaSizeNames != null) && (mediaSizeNames.length > 0)) {
                     // if 'mediaSizeNames' is not null, idList and mediaSizes
                     // cannot be null but to be safe, add a check
                     if ((idList != null) && (mediaSizes != null) &&
                         (idList.size() == mediaSizes.length)) {
                         Integer defIdObj = Integer.valueOf(defPaper);
                         int index = idList.indexOf(defIdObj);
                         if (index>=0 && index<mediaSizes.length) {
                             return mediaSizes[index].getMediaSizeName();
                         }
                     }

                     return mediaSizeNames[0];
                 }
             }
        } else if (category == MediaPrintableArea.class) {
            /* Verify defPaper */
            MediaSizeName msn = findWin32Media(defPaper);
            if (msn != null &&
                !isSupportedMedia(msn) && mediaSizeNames != null) {
                defPaper = findPaperID(mediaSizeNames[0]);
            }
            float[] prnArea = getMediaPrintableArea(printer, defPaper);
            if (prnArea != null) {
                MediaPrintableArea printableArea = null;
                try {
                    printableArea = new MediaPrintableArea(prnArea[0],
                                                           prnArea[1],
                                                           prnArea[2],
                                                           prnArea[3],
                                                           MediaPrintableArea.INCH);
                } catch (IllegalArgumentException e) {
                }
                return printableArea;
            }
            return null;
        } else if (category == SunAlternateMedia.class) {
            return null;
        } else if (category == Destination.class) {
            return new Destination((new File("out.prn")).toURI());
        } else if (category == Sides.class) {
            switch(defSides) {
            case DMDUP_VERTICAL :
                return Sides.TWO_SIDED_LONG_EDGE;
            case DMDUP_HORIZONTAL :
                return Sides.TWO_SIDED_SHORT_EDGE;
            default :
                return Sides.ONE_SIDED;
            }
        } else if (category == PrinterResolution.class) {
            int yRes = defYRes;
            int xRes = defQuality;
            if ((xRes < 0) || (yRes < 0)) {
                int res = (yRes > xRes) ? yRes : xRes;
                if (res > 0) {
                 return new PrinterResolution(res, res, PrinterResolution.DPI);
                }
            }
            else {
               return new PrinterResolution(xRes, yRes, PrinterResolution.DPI);
            }
        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return ColorSupported.SUPPORTED;
            } else {
                return ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == PrintQuality.class) {
            if ((defQuality < 0) && (defQuality >= DMRES_HIGH)) {
                switch (defQuality) {
                case DMRES_HIGH:
                    return PrintQuality.HIGH;
                case DMRES_MEDIUM:
                    return PrintQuality.NORMAL;
                default:
                    return PrintQuality.DRAFT;
                }
            }
        } else if (category == RequestingUserName.class) {
            String userName = System.getProperty("user.name", "");
            return new RequestingUserName(userName, null);
        } else if (category == SheetCollate.class) {
            if (defCollate == DMCOLLATE_TRUE) {
                return SheetCollate.COLLATED;
            } else {
                return SheetCollate.UNCOLLATED;
            }
        } else if (category == Fidelity.class) {
            return Fidelity.FIDELITY_FALSE;
        }
        return null;
    }

    private boolean isPostScriptFlavor(DocFlavor flavor) {
        if (flavor.equals(DocFlavor.BYTE_ARRAY.POSTSCRIPT) ||
            flavor.equals(DocFlavor.INPUT_STREAM.POSTSCRIPT) ||
            flavor.equals(DocFlavor.URL.POSTSCRIPT)) {
            return true;
        }
        else {
            return false;
        }
    }

    private boolean isPSDocAttr(Class<?> category) {
        if (category == OrientationRequested.class || category == Copies.class) {
                return true;
        }
        else {
            return false;
        }
    }

    private boolean isAutoSense(DocFlavor flavor) {
        if (flavor.equals(DocFlavor.BYTE_ARRAY.AUTOSENSE) ||
            flavor.equals(DocFlavor.INPUT_STREAM.AUTOSENSE) ||
            flavor.equals(DocFlavor.URL.AUTOSENSE)) {
            return true;
        }
        else {
            return false;
        }
    }

    @Override
    public Object
        getSupportedAttributeValues(Class<? extends Attribute> category,
                                    DocFlavor flavor,
                                    AttributeSet attributes)
    {
        if (category == null) {
            throw new NullPointerException("null category");
        }
        if (!Attribute.class.isAssignableFrom(category)) {
            throw new IllegalArgumentException(category +
                                             " does not implement Attribute");
        }
        if (flavor != null) {
            if (!isDocFlavorSupported(flavor)) {
                throw new IllegalArgumentException(flavor +
                                                  " is an unsupported flavor");
                // if postscript & category is already specified within the
                //  PostScript data we return null
            } else if (isAutoSense(flavor) ||(isPostScriptFlavor(flavor) &&
                       (isPSDocAttr(category)))){
                return null;
            }
        }
        if (!isAttributeCategorySupported(category)) {
            return null;
        }

        if (category == JobName.class) {
            return new JobName("Java Printing", null);
        } else if (category == RequestingUserName.class) {
            String userName = System.getProperty("user.name", "");
            return new RequestingUserName(userName, null);
        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            if ((caps & DEVCAP_COLOR) != 0) {
                return ColorSupported.SUPPORTED;
            } else {
                return ColorSupported.NOT_SUPPORTED;
            }
        } else if (category == Chromaticity.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                int caps = getPrinterCapabilities();
                if ((caps & DEVCAP_COLOR) == 0) {
                    Chromaticity []arr = new Chromaticity[1];
                    arr[0] = Chromaticity.MONOCHROME;
                    return (arr);
                } else {
                    Chromaticity []arr = new Chromaticity[2];
                    arr[0] = Chromaticity.MONOCHROME;
                    arr[1] = Chromaticity.COLOR;
                    return (arr);
                }
            } else {
                return null;
            }
        } else if (category == Destination.class) {
            return new Destination((new File("out.prn")).toURI());
        } else if (category == OrientationRequested.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                OrientationRequested []arr = new OrientationRequested[3];
                arr[0] = OrientationRequested.PORTRAIT;
                arr[1] = OrientationRequested.LANDSCAPE;
                arr[2] = OrientationRequested.REVERSE_LANDSCAPE;
                return arr;
            } else {
                return null;
            }
        } else if ((category == Copies.class) ||
                   (category == CopiesSupported.class)) {
            synchronized (this) {
                if (gotCopies == false) {
                    nCopies = getCopiesSupported(printer, getPort());
                    gotCopies = true;
                }
            }
            return new CopiesSupported(1, nCopies);
        } else if (category == Media.class) {

            initMedia();

            int len = (mediaSizeNames == null) ? 0 : mediaSizeNames.length;

            MediaTray[] trays = getMediaTrays();

            len += (trays == null) ? 0 : trays.length;

            Media []arr = new Media[len];
            if (mediaSizeNames != null) {
                System.arraycopy(mediaSizeNames, 0, arr,
                                 0, mediaSizeNames.length);
            }
            if (trays != null) {
                System.arraycopy(trays, 0, arr,
                                 len - trays.length, trays.length);
            }
            return arr;
        } else if (category == MediaPrintableArea.class) {
            // if getting printable area for a specific media size
            Media mediaName = null;
            if ((attributes != null) &&
                ((mediaName =
                  (Media)attributes.get(Media.class)) != null)) {

                if (!(mediaName instanceof MediaSizeName)) {
                    // if an instance of MediaTray, fall thru returning
                    // all MediaPrintableAreas
                    mediaName = null;
                }
            }

            MediaPrintableArea[] mpas =
                                  getMediaPrintables((MediaSizeName)mediaName);
            if (mpas != null) {
                MediaPrintableArea[] arr = new MediaPrintableArea[mpas.length];
                System.arraycopy(mpas, 0, arr, 0, mpas.length);
                return arr;
            } else {
                return null;
            }
        } else if (category == SunAlternateMedia.class) {
            return new SunAlternateMedia(
                              (Media)getDefaultAttributeValue(Media.class));
        } else if (category == PageRanges.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                PageRanges []arr = new PageRanges[1];
                arr[0] = new PageRanges(1, Integer.MAX_VALUE);
                return arr;
            } else {
                return null;
            }
        } else if (category == PrinterResolution.class) {
            PrinterResolution[] supportedRes = getPrintResolutions();
            if (supportedRes == null) {
                return null;
            }
            PrinterResolution []arr =
                new PrinterResolution[supportedRes.length];
            System.arraycopy(supportedRes, 0, arr, 0, supportedRes.length);
            return arr;
        } else if (category == Sides.class) {
            if (flavor == null ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE)) {
                Sides []arr = new Sides[3];
                arr[0] = Sides.ONE_SIDED;
                arr[1] = Sides.TWO_SIDED_LONG_EDGE;
                arr[2] = Sides.TWO_SIDED_SHORT_EDGE;
                return arr;
            } else {
                return null;
            }
        } else if (category == PrintQuality.class) {
            PrintQuality []arr = new PrintQuality[3];
            arr[0] = PrintQuality.DRAFT;
            arr[1] = PrintQuality.HIGH;
            arr[2] = PrintQuality.NORMAL;
            return arr;
        } else if (category == SheetCollate.class) {
            if (flavor == null ||
                (flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                 flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                SheetCollate []arr = new SheetCollate[2];
                arr[0] = SheetCollate.COLLATED;
                arr[1] = SheetCollate.UNCOLLATED;
                return arr;
            } else {
                return null;
            }
        } else if (category == Fidelity.class) {
            Fidelity []arr = new Fidelity[2];
            arr[0] = Fidelity.FIDELITY_FALSE;
            arr[1] = Fidelity.FIDELITY_TRUE;
            return arr;
        } else {
            return null;
        }
    }

    @Override
    public boolean isAttributeValueSupported(Attribute attr,
                                             DocFlavor flavor,
                                             AttributeSet attributes) {

        if (attr == null) {
            throw new NullPointerException("null attribute");
        }
        Class<? extends Attribute> category = attr.getCategory();
        if (flavor != null) {
            if (!isDocFlavorSupported(flavor)) {
                throw new IllegalArgumentException(flavor +
                                                   " is an unsupported flavor");
                // if postscript & category is already specified within the PostScript data
                // we return false
            } else if (isAutoSense(flavor) || (isPostScriptFlavor(flavor) &&
                       (isPSDocAttr(category)))) {
                return false;
            }
        }

        if (!isAttributeCategorySupported(category)) {
            return false;
        }
        else if (category == Chromaticity.class) {
            if ((flavor == null) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.URL.PNG)) {
                int caps = getPrinterCapabilities();
                if ((caps & DEVCAP_COLOR) != 0) {
                    return true;
                } else {
                    return attr == Chromaticity.MONOCHROME;
                }
            } else {
                return false;
            }
        } else if (category == Copies.class) {
            return isSupportedCopies((Copies)attr);

        } else if (category == Destination.class) {
            URI uri = ((Destination)attr).getURI();
            if ("file".equals(uri.getScheme()) &&
                !uri.getSchemeSpecificPart().isEmpty()) {
                return true;
            } else {
            return false;
            }

        } else if (category == Media.class) {
            if (attr instanceof MediaSizeName) {
                return isSupportedMedia((MediaSizeName)attr);
            }
            if (attr instanceof MediaTray) {
                return isSupportedMediaTray((MediaTray)attr);
            }

        } else if (category == MediaPrintableArea.class) {
            return isSupportedMediaPrintableArea((MediaPrintableArea)attr);

        } else if (category == SunAlternateMedia.class) {
            Media media = ((SunAlternateMedia)attr).getMedia();
            return isAttributeValueSupported(media, flavor, attributes);

        } else if (category == PageRanges.class ||
                   category == SheetCollate.class ||
                   category == Sides.class) {
            if (flavor != null &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE))) {
                return false;
            }
        } else if (category == PrinterResolution.class) {
            if (attr instanceof PrinterResolution) {
                return isSupportedResolution((PrinterResolution)attr);
            }
        } else if (category == OrientationRequested.class) {
            if (attr == OrientationRequested.REVERSE_PORTRAIT ||
                (flavor != null) &&
                !(flavor.equals(DocFlavor.SERVICE_FORMATTED.PAGEABLE) ||
                flavor.equals(DocFlavor.SERVICE_FORMATTED.PRINTABLE) ||
                flavor.equals(DocFlavor.INPUT_STREAM.GIF) ||
                flavor.equals(DocFlavor.INPUT_STREAM.JPEG) ||
                flavor.equals(DocFlavor.INPUT_STREAM.PNG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.GIF) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.JPEG) ||
                flavor.equals(DocFlavor.BYTE_ARRAY.PNG) ||
                flavor.equals(DocFlavor.URL.GIF) ||
                flavor.equals(DocFlavor.URL.JPEG) ||
                flavor.equals(DocFlavor.URL.PNG))) {
                return false;
            }

        } else if (category == ColorSupported.class) {
            int caps = getPrinterCapabilities();
            boolean isColorSup = ((caps & DEVCAP_COLOR) != 0);
            if  ((!isColorSup && (attr == ColorSupported.SUPPORTED)) ||
                (isColorSup && (attr == ColorSupported.NOT_SUPPORTED))) {
                return false;
            }
        } else if (category == DialogTypeSelection.class) {
            return true; // isHeadless was checked by category support
        } else if (category == DialogOwner.class) {
            DialogOwner owner = (DialogOwner)attr;
            DialogTypeSelection dts = (attributes == null) ? null :
                (DialogTypeSelection)attributes.get(DialogTypeSelection.class);
            if (dts == DialogTypeSelection.NATIVE) {
                return DialogOwnerAccessor.getID(owner) != 0;
            } else {
               if (DialogOwnerAccessor.getID(owner) != 0) {
                  return false;
               } else if (owner.getOwner() != null) {
                   return true;
               } else {
                   return Toolkit.getDefaultToolkit().isAlwaysOnTopSupported();
               }
            }
        }
        return true;
    }

    @Override
    public AttributeSet getUnsupportedAttributes(DocFlavor flavor,
                                                 AttributeSet attributes) {

        if (flavor != null && !isDocFlavorSupported(flavor)) {
            throw new IllegalArgumentException("flavor " + flavor +
                                               " is not supported");
        }

        if (attributes == null) {
            return null;
        }

        Attribute attr;
        AttributeSet unsupp = new HashAttributeSet();
        Attribute []attrs = attributes.toArray();
        for (int i=0; i<attrs.length; i++) {
            try {
                attr = attrs[i];
                if (!isAttributeCategorySupported(attr.getCategory())) {
                    unsupp.add(attr);
                }
                else if (!isAttributeValueSupported(attr, flavor, attributes)) {
                    unsupp.add(attr);
                }
            } catch (ClassCastException e) {
            }
        }
        if (unsupp.isEmpty()) {
            return null;
        } else {
            return unsupp;
        }
    }

    private Win32DocumentPropertiesUI docPropertiesUI = null;

    private static final class Win32DocumentPropertiesUI
        extends DocumentPropertiesUI {

        Win32PrintService service;

        private Win32DocumentPropertiesUI(Win32PrintService s) {
            service = s;
        }

        @Override
        public PrintRequestAttributeSet
            showDocumentProperties(PrinterJob job,
                                   Window owner,
                                   PrintService service,
                                   PrintRequestAttributeSet aset) {

            if (!(job instanceof WPrinterJob)) {
                return null;
            }
            WPrinterJob wJob = (WPrinterJob)job;
            return wJob.showDocumentProperties(owner, service, aset);
        }
    }

    private synchronized DocumentPropertiesUI getDocumentPropertiesUI() {
        return new Win32DocumentPropertiesUI(this);
    }

    private static final class Win32ServiceUIFactory extends ServiceUIFactory {

        Win32PrintService service;

        Win32ServiceUIFactory(Win32PrintService s) {
            service = s;
        }

        @Override
        public Object getUI(int role, String ui) {
            if (role <= ServiceUIFactory.MAIN_UIROLE) {
                return null;
            }
            if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE &&
                DocumentPropertiesUI.DOCPROPERTIESCLASSNAME.equals(ui))
            {
                return service.getDocumentPropertiesUI();
            }
            throw new IllegalArgumentException("Unsupported role");
        }

        @Override
        public String[] getUIClassNamesForRole(int role) {

            if (role <= ServiceUIFactory.MAIN_UIROLE) {
                return null;
            }
            if (role == DocumentPropertiesUI.DOCUMENTPROPERTIES_ROLE) {
                String[] names = new String[0];
                names[0] = DocumentPropertiesUI.DOCPROPERTIESCLASSNAME;
                return names;
            }
            throw new IllegalArgumentException("Unsupported role");
        }
    }

    private Win32ServiceUIFactory uiFactory = null;

    @Override
    public synchronized ServiceUIFactory getServiceUIFactory() {
        if (uiFactory == null) {
            uiFactory = new Win32ServiceUIFactory(this);
        }
        return uiFactory;
    }

    @Override
    public String toString() {
        return "Win32 Printer : " + getName();
    }

    @Override
    public boolean equals(Object obj) {
        return  (obj == this ||
                 (obj instanceof Win32PrintService &&
                  ((Win32PrintService)obj).getName().equals(getName())));
    }

   @Override
   public int hashCode() {
        return this.getClass().hashCode()+getName().hashCode();
    }

    @Override
    public boolean usesClass(Class<?> c) {
        return (c == sun.awt.windows.WPrinterJob.class);
    }

    private native int[] getAllMediaIDs(String printerName, String port);
    private native int[] getAllMediaSizes(String printerName, String port);
    private native int[] getAllMediaTrays(String printerName, String port);
    private native float[] getMediaPrintableArea(String printerName,
                                                 int paperSize);
    private native String[] getAllMediaNames(String printerName, String port);
    private native String[] getAllMediaTrayNames(String printerName, String port);
    private native int getCopiesSupported(String printerName, String port);
    private native int[] getAllResolutions(String printerName, String port);
    private native int getCapabilities(String printerName, String port);

    private native int[] getDefaultSettings(String printerName, String port);
    private native int getJobStatus(String printerName, int type);
    private native String getPrinterPort(String printerName);
}

@SuppressWarnings("serial") // JDK implementation class
final class Win32MediaSize extends MediaSizeName {
    private static ArrayList<String> winStringTable = new ArrayList<>();
    private static ArrayList<Win32MediaSize> winEnumTable = new ArrayList<>();
    private static MediaSize[] predefMedia;

    private int dmPaperID; // driver ID for this paper.

    private Win32MediaSize(int x) {
        super(x);

    }

    private static synchronized int nextValue(String name) {
      winStringTable.add(name);
      return (winStringTable.size()-1);
    }

    public static synchronized Win32MediaSize findMediaName(String name) {
        int nameIndex = winStringTable.indexOf(name);
        if (nameIndex != -1) {
            return winEnumTable.get(nameIndex);
        }
        return null;
    }

    public static MediaSize[] getPredefMedia() {
        return predefMedia;
    }

    public Win32MediaSize(String name, int dmPaper) {
        super(nextValue(name));
        dmPaperID = dmPaper;
        winEnumTable.add(this);
    }

    private MediaSizeName[] getSuperEnumTable() {
      return (MediaSizeName[])super.getEnumValueTable();
    }

    static {
         /* initialize predefMedia */
        {
            Win32MediaSize winMedia = new Win32MediaSize(-1);

            // cannot call getSuperEnumTable directly because of static context
            MediaSizeName[] enumMedia = winMedia.getSuperEnumTable();
            if (enumMedia != null) {
                predefMedia = new MediaSize[enumMedia.length];

                for (int i=0; i<enumMedia.length; i++) {
                    predefMedia[i] = MediaSize.getMediaSizeForName(enumMedia[i]);
                }
            }
        }
    }

    int getDMPaper() {
        return dmPaperID;
    }

    @Override
    protected String[] getStringTable() {
      String[] nameTable = new String[winStringTable.size()];
      return winStringTable.toArray(nameTable);
    }

    @Override
    protected EnumSyntax[] getEnumValueTable() {
      MediaSizeName[] enumTable = new MediaSizeName[winEnumTable.size()];
      return winEnumTable.toArray(enumTable);
    }

}
