text:
/**
 * @author Pavel Dolgov, Dmitry A. Durnev
 */
package org.apache.harmony.awt.wtk.windows;

import java.awt.Color;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.font.TextAttribute;
import java.awt.im.InputMethodHighlight;
import java.util.Map;
import java.util.TreeSet;
import org.apache.harmony.awt.ComponentInternals;
import org.apache.harmony.awt.nativebridge.Int16Pointer;
import org.apache.harmony.awt.nativebridge.Int32Pointer;
import org.apache.harmony.awt.nativebridge.NativeBridge;
import org.apache.harmony.awt.nativebridge.windows.Win32;
import org.apache.harmony.awt.nativebridge.windows.WindowsDefs;
import org.apache.harmony.awt.wtk.SystemProperties;

/**
 * WinSystemProperties
 * More information about Windows Desktop Properties can be found at http://java.sun.com/j2se/1.5.0/docs/guide/swing/1.4/w2k_props.html
 */

public class WinSystemProperties implements SystemProperties {

    private static final Win32 win32 = Win32.getInstance();

    private static final int SPI_GETFONTSMOOTHINGTYPE = 0x200A;
    private static final int SPI_SETFONTSMOOTHINGTYPE = 0x200B;
    private static final int SPI_GETFONTSMOOTHINGCONTRAST = 0x200C;
    private static final int SPI_SETFONTSMOOTHINGCONTRAST = 0x200D;

    private static final int sysColorIndices[] = {    // SystemColor.* constants
            WindowsDefs.COLOR_DESKTOP,          // 0 DESKTOP
            WindowsDefs.COLOR_ACTIVECAPTION,    // 1 ACTIVE_CAPTION
            WindowsDefs.COLOR_CAPTIONTEXT,      // 2 ACTIVE_CAPTION_TEXT
            WindowsDefs.COLOR_ACTIVEBORDER,     // 3 ACTIVE_CAPTION_BORDER
            WindowsDefs.COLOR_INACTIVECAPTION,  // 4 INACTIVE_CAPTION
            WindowsDefs.COLOR_INACTIVECAPTIONTEXT, // 5 INACTIVE_CAPTION_TEXT
            WindowsDefs.COLOR_INACTIVEBORDER,   // 6 INACTIVE_CAPTION_BORDER
            WindowsDefs.COLOR_WINDOW,           // 7 WINDOW
            WindowsDefs.COLOR_WINDOWFRAME,      // 8 WINDOW_BORDER
            WindowsDefs.COLOR_WINDOWTEXT,       // 9 WINDOW_TEXT
            WindowsDefs.COLOR_MENU,             // 10 MENU
            WindowsDefs.COLOR_MENUTEXT,         // 11 MENU_TEXT
            WindowsDefs.COLOR_WINDOW,           // 12 TEXT
            WindowsDefs.COLOR_WINDOWTEXT,       // 13 TEXT_TEXT
            WindowsDefs.COLOR_HIGHLIGHT,        // 14 TEXT_HIGHLIGHT
            WindowsDefs.COLOR_HIGHLIGHTTEXT,    // 15 TEXT_HIGHLIGHT_TEXT
            WindowsDefs.COLOR_GRAYTEXT,         // 16 TEXT_INACTIVE_TEXT
            WindowsDefs.COLOR_3DFACE,           // 17 CONTROL
            WindowsDefs.COLOR_BTNTEXT,          // 18 CONTROL_TEXT
            WindowsDefs.COLOR_3DLIGHT,          // 19 CONTROL_HIGHLIGHT
            WindowsDefs.COLOR_3DHILIGHT,        // 20 CONTROL_LT_HIGHLIGHT
            WindowsDefs.COLOR_3DSHADOW,         // 21 CONTROL_SHADOW
            WindowsDefs.COLOR_3DDKSHADOW,       // 22 CONTROL_DK_SHADOW
            WindowsDefs.COLOR_SCROLLBAR,        // 23 SCROLLBAR
            WindowsDefs.COLOR_INFOBK,           // 24 INFO
            WindowsDefs.COLOR_INFOTEXT,         // 25 INFO_TEXT
            // colors not present in SystemColor class:
            WindowsDefs.COLOR_GRADIENTACTIVECAPTION,
            WindowsDefs.COLOR_GRADIENTINACTIVECAPTION,
            WindowsDefs.COLOR_HOTLIGHT,
            WindowsDefs.COLOR_APPWORKSPACE,
            WindowsDefs.COLOR_MENUBAR,
    };

    private static final String sysColorProps[] = { // color property names
            "win.desktop.backgroundColor", // 0 DESKTOP //$NON-NLS-1$
            "win.frame.activeCaptionColor", // 1 ACTIVE_CAPTION //$NON-NLS-1$
            "win.frame.captionTextColor", // 2 ACTIVE_CAPTION_TEXT //$NON-NLS-1$
            "win.frame.activeBorderColor", // 3 ACTIVE_CAPTION_BORDER //$NON-NLS-1$
            "win.frame.inactiveCaptionColor", // 4 INACTIVE_CAPTION //$NON-NLS-1$
            "win.frame.inactiveCaptionTextColor", // 5 INACTIVE_CAPTION_TEXT //$NON-NLS-1$
            "win.frame.inactiveBorderColor", // 6 INACTIVE_CAPTION_BORDER //$NON-NLS-1$
            "win.frame.backgroundColor", // 7 WINDOW //$NON-NLS-1$
            "win.frame.color", //? 8 WINDOW_BORDER //$NON-NLS-1$
            "win.frame.textColor", // 9 WINDOW_TEXT //$NON-NLS-1$
            "win.menu.backgroundColor", // 10 MENU //$NON-NLS-1$
            "win.menu.textColor", // 11 MENU_TEXT //$NON-NLS-1$
            "win.frame.backgroundColor", // 12 TEXT //$NON-NLS-1$
            "win.frame.textColor", // 13 TEXT_TEXT //$NON-NLS-1$
            "win.item.highlightColor", // 14 TEXT_HIGHLIGHT //$NON-NLS-1$
            "win.item.highlightTextColor", // 15 TEXT_HIGHLIGHT_TEXT //$NON-NLS-1$
            "win.text.grayedTextColor", // 16 TEXT_INACTIVE_TEXT //$NON-NLS-1$
            "win.3d.backgroundColor", // 17 CONTROL //$NON-NLS-1$
            "win.button.textColor", // 18 CONTROL_TEXT //$NON-NLS-1$
            "win.3d.lightColor", // 19 CONTROL_HIGHLIGHT //$NON-NLS-1$
            "win.3d.highlightColor", // 20 CONTROL_LT_HIGHLIGHT //$NON-NLS-1$
            "win.3d.shadowColor", // 21 CONTROL_SHADOW //$NON-NLS-1$
            "win.3d.darkShadowColor", // 22 CONTROL_DK_SHADOW //$NON-NLS-1$
            "win.scrollbar.backgroundColor", // 23 SCROLLBAR //$NON-NLS-1$
            "win.tooltip.backgroundColor", // 24 INFO //$NON-NLS-1$
            "win.tooltip.textColor", // 25 INFO_TEXT //$NON-NLS-1$
            // colors not present in SystemColor class:
            "win.frame.activeCaptionGradientColor", //$NON-NLS-1$
            "win.frame.inactiveCaptionGradientColor", //$NON-NLS-1$
            "win.item.hotTrackedColor", //$NON-NLS-1$
            "win.mdi.backgroundColor", //$NON-NLS-1$
            "win.menubar.backgroundColor", //$NON-NLS-1$
    };

    private static final int sysFontIndices[] = {

        WindowsDefs.ANSI_FIXED_FONT,
        WindowsDefs.ANSI_VAR_FONT,
        WindowsDefs.DEFAULT_GUI_FONT,
        WindowsDefs.DEVICE_DEFAULT_FONT,
        WindowsDefs.OEM_FIXED_FONT,
        WindowsDefs.SYSTEM_FONT,
        WindowsDefs.SYSTEM_FIXED_FONT,

    };

    private static final String sysFontDesktopProps[] = { // color property names
            "win.ansiFixed.font", // 0 ANSI_FIXED_FONT //$NON-NLS-1$
            "win.ansiVar.font", // 1 ANSI_VAR_FONT //$NON-NLS-1$
            "win.defaultGUI.font", // 2 DEFAULT_GUI_FONT //$NON-NLS-1$
            "win.deviceDefault.font", // 3 DEVICE_DEFAULT_FONT             //$NON-NLS-1$
            "win.oemFixed.font", // 4 OEM_FIXED_FONT             //$NON-NLS-1$
            "win.system.font", // 5 SYSTEM_FONT //$NON-NLS-1$
            "win.systemFixed.font", // 6 SYSTEM_FIXED_FONT             //$NON-NLS-1$
    };

    private class WinPlaySound implements Runnable {
        final String sndName;

        WinPlaySound(String snd) {
            sndName = snd;
        }

        public void run() {
            final int flags = (WindowsDefs.SND_ALIAS | WindowsDefs.SND_SYNC |
                               WindowsDefs.SND_NODEFAULT);
            // have to start another thread to wait until playing ends
            new Thread() {
                @Override
                public void run() {
                    win32.PlaySoundW(sndName, 0, flags);
                }
            }.start();
        }

        @Override
        public String toString() {
            return ("WinPlaySound(" + sndName + ")"); //$NON-NLS-1$ //$NON-NLS-2$
        }
    };

    private int sysColorCache[];

    private Font defaultFont;

    private class CacheLock {}
    private final Object cacheLock = new CacheLock();

    public int getSystemColorARGB(int index) {
        synchronized (cacheLock) {
            if (sysColorCache == null) {
                updateColorCache();
            }
            return sysColorCache[index];
        }
    }

    void resetSystemColors() {
        synchronized (cacheLock) {
            sysColorCache = null;
            updateColorCache();
            updateColorDesktopProperties(null);
        }
    }

    private void updateColorCache() {
        sysColorCache = new int[sysColorIndices.length];
        for (int i=0; i<sysColorIndices.length; i++) {
            int n = sysColorIndices[i];
            int bgr = win32.GetSysColor(n);
            int b = (bgr & 0xFF0000) >> 16;
            int g = (bgr & 0xFF00);
            int r = (bgr & 0xFF) << 16;
            sysColorCache[i] = (0xFF000000 | r | g | b);

        }
    }

    private void updateColorDesktopProperties(Map<String, Object> props) {
        for (int i = 0; i < sysColorIndices.length; i++) {
            String name = sysColorProps[i];
            Color val = new Color(sysColorCache[i]);

            setDesktopProperty(name, val, props);
        }
    }

    private void setDesktopProperty(String name, Object val, Map<String, Object> props) {
        if (props != null) {
            props.put(name, val);
            return; // skip firing property change
        }
        ComponentInternals ci = ComponentInternals.getComponentInternals();
        ci.setDesktopProperty(name, val);
    }

    public Font getDefaultFont() {
        synchronized (cacheLock) {
            if (defaultFont == null) {
                defaultFont = (Font) Toolkit.getDefaultToolkit().
                getDesktopProperty("win.defaultGUI.font"); //$NON-NLS-1$
            }
            return defaultFont;
        }
    }

    private Font getFont(long hFont) {
        Win32.LOGFONTW logFont = win32.createLOGFONTW(false);
        win32.GetObjectW(hFont, logFont.size(), logFont.longLockPointer());
        logFont.unlock();
        return getFont(logFont);
    }

    private Font getFont(Win32.LOGFONTW logFont) {
        String name = logFont.get_lfFaceName().getString();
        int size = Math.abs(logFont.get_lfHeight());
        int weight = logFont.get_lfWeight();
        int bold = (weight == WindowsDefs.FW_BOLD ? Font.BOLD : 0);
        int italic = (logFont.get_lfItalic() != 0) ? Font.ITALIC : 0;
        return new Font(name, bold | italic, size);
    }

    private void initSysFonts(Map<String, Object> props) {
        for (int i = 0; i < sysFontIndices.length; i++) {
            long hFont = win32.GetStockObject(sysFontIndices[i]);
            Font font = getFont(hFont);
            if (props != null) {
                String propName = sysFontDesktopProps[i];
                setFontProperty(propName, font, props);
            }
        }
    }

    private void setBoolProperty(String propName, int val, Map<String, Object> props) {
        setDesktopProperty(propName, (val != 0 ? Boolean.TRUE : Boolean.FALSE),
                           props);
    }

    private void setIntProperty(String propName, int val, Map<String, Object> props) {
        setDesktopProperty(propName, new Integer(val), props);
    }

    private void setFontProperty(String propName, Font font, Map<String, Object> props) {
        setDesktopProperty(propName, font, props);
        setIntProperty(propName + ".height", font.getSize(), props); //$NON-NLS-1$
    }

    @SuppressWarnings("unchecked") //$NON-NLS-1$
    public void init(Map<String, ?> deskProps) {
        Map<String, Object> desktopProperties = (Map<String, Object>)deskProps;
        synchronized (cacheLock) {
            getDnDProps(desktopProperties);
            getShellProps(desktopProperties);
            getMouseProps(desktopProperties);
            if (sysColorCache == null) {
                updateColorCache();
            }
            updateColorDesktopProperties(desktopProperties);
            initSysFonts(desktopProperties);
            getNonClientMetrics(desktopProperties);
            getIconMetrics(desktopProperties);
            getDragSize(true, desktopProperties);
            getDragSize(false, desktopProperties);
            getGradientCaptions(desktopProperties);
            getFullWindowDrags(desktopProperties);
            getHighContrast(desktopProperties);
            getHotTracking(desktopProperties);
            getKeyboardCues(desktopProperties);
            getFontSmooth(desktopProperties);
            getFontSmoothContrast(desktopProperties);
            getFontSmoothType(desktopProperties);
            getXPTheme(desktopProperties);
            initSoundProps(desktopProperties);
            TreeSet<String> keySet = new TreeSet<String>(desktopProperties.keySet());
            keySet.add("awt.dynamicLayoutSupported"); //$NON-NLS-1$
            String[] propNames = keySet.toArray(new String[0]);
            desktopProperties.put("win.propNames", propNames); //$NON-NLS-1$

        }

    }

    void processSettingChange(long idx) {
        switch((int)idx) {
        case WindowsDefs.SPI_SETNONCLIENTMETRICS:
            getNonClientMetrics(null);
            break;
        case WindowsDefs.SPI_SETICONMETRICS:
            getIconMetrics(null);
            break;
        case WindowsDefs.SPI_SETDRAGHEIGHT:
        case WindowsDefs.SPI_SETDRAGWIDTH:
            getDragSize(idx == WindowsDefs.SPI_SETDRAGWIDTH, null);
            break;
        case WindowsDefs.SPI_SETGRADIENTCAPTIONS:
            getGradientCaptions(null);
            break;
        case WindowsDefs.SPI_SETDRAGFULLWINDOWS:
            getFullWindowDrags(null);
            break;
        case WindowsDefs.SPI_SETHIGHCONTRAST:
            getHighContrast(null);
            break;
        case WindowsDefs.SPI_SETHOTTRACKING:
            getHotTracking(null);
            break;
        case WindowsDefs.SPI_SETKEYBOARDCUES:
            getKeyboardCues(null);
            break;
        case WindowsDefs.SPI_SETFONTSMOOTHING:
            getFontSmooth(null);
            break;
        case SPI_SETFONTSMOOTHINGCONTRAST:
            getFontSmoothContrast(null);
            break;
        case SPI_SETFONTSMOOTHINGTYPE:
            getFontSmoothType(null);
            break;
        case WindowsDefs.SPI_SETDOUBLECLICKTIME:
        case WindowsDefs.SPI_SETWHEELSCROLLLINES:
            getMouseProps(null);
            break;
        }

    }

    private void getFullWindowDrags(Map<String, Object> props) {
        getBoolSPI("win.frame.fullWindowDragsOn",  //$NON-NLS-1$
                   WindowsDefs.SPI_GETDRAGFULLWINDOWS, props);

    }

    private void getGradientCaptions(Map<String, Object> props) {
        getBoolSPI("win.frame.captionGradientsOn",  //$NON-NLS-1$
                   WindowsDefs.SPI_GETGRADIENTCAPTIONS, props);
    }

    private void getHotTracking(Map<String, Object> props) {
        getBoolSPI("win.item.hotTrackingOn",  //$NON-NLS-1$
                   WindowsDefs.SPI_GETHOTTRACKING, props);
    }

    private void getKeyboardCues(Map<String, Object> props) {
        getBoolSPI("win.menu.keyboardCuesOn",  //$NON-NLS-1$
                   WindowsDefs.SPI_GETKEYBOARDCUES, props);
    }

    private void getFontSmooth(Map<String, Object> props) {
        getBoolSPI("win.text.fontSmoothingOn",  //$NON-NLS-1$
                   WindowsDefs.SPI_GETFONTSMOOTHING, props);
    }

    private void getFontSmoothContrast(Map<String, Object> props) {
        getIntSPI("win.text.fontSmoothingContrast", //$NON-NLS-1$
                  SPI_GETFONTSMOOTHINGCONTRAST, props);
    }

    private void getFontSmoothType(Map<String, Object> props) {
        getIntSPI("win.text.fontSmoothingType", SPI_GETFONTSMOOTHINGTYPE, props); //$NON-NLS-1$
    }

    private void getDragSize(boolean cx, Map<String, Object> props) {
        int sm_idx = (cx ? WindowsDefs.SM_CXDRAG : WindowsDefs.SM_CYDRAG);
        String propName = "win.drag"; //$NON-NLS-1$
        propName += (cx ? ".width" : ".height"); //$NON-NLS-1$ //$NON-NLS-2$
        getSM(propName, sm_idx, props);
    }

    private void getNonClientMetrics(Map<String, Object> props) {
        Win32.NONCLIENTMETRICSW ncm = win32.createNONCLIENTMETRICSW(false);
        ncm.set_cbSize(ncm.size());
        win32.SystemParametersInfoW(WindowsDefs.SPI_GETNONCLIENTMETRICS,
                                    ncm.size(), ncm.getElementPointer(0), 0);
        setFontProperty("win.frame.captionFont", //$NON-NLS-1$
                        getFont(ncm.get_lfCaptionFont()), props);
        setFontProperty("win.frame.smallCaptionFont", //$NON-NLS-1$
                        getFont(ncm.get_lfSmCaptionFont()), props);
        setFontProperty("win.menu.font", getFont(ncm.get_lfMenuFont()), props); //$NON-NLS-1$
        setFontProperty("win.messagebox.font", //$NON-NLS-1$
                        getFont(ncm.get_lfMessageFont()), props);
        setFontProperty("win.status.font", getFont(ncm.get_lfStatusFont()), //$NON-NLS-1$
                        props);
        setFontProperty("win.tooltip.font", getFont(ncm.get_lfStatusFont()), //$NON-NLS-1$
                        props);
        setIntProperty("win.frame.sizingBorderWidth", ncm.get_iBorderWidth(), //$NON-NLS-1$
                       props);
        setIntProperty("win.scrollbar.width", ncm.get_iScrollWidth(), //$NON-NLS-1$
                       props);
        setIntProperty("win.scrollbar.height", ncm.get_iScrollHeight(), //$NON-NLS-1$
                       props);
        setIntProperty("win.frame.captionButtonWidth", ncm.get_iCaptionWidth(), //$NON-NLS-1$
                       props);
        setIntProperty("win.frame.captionButtonHeight", ncm.get_iCaptionHeight(), //$NON-NLS-1$
                       props);
        setIntProperty("win.frame.captionHeight", ncm.get_iCaptionHeight(), //$NON-NLS-1$
                       props);
        setIntProperty("win.frame.smallCaptionButtonWidth", ncm.get_iSmCaptionWidth(), //$NON-NLS-1$
                       props);
        setIntProperty("win.frame.smallCaptionButtonHeight", ncm.get_iSmCaptionHeight(), //$NON-NLS-1$
                       props);
        setIntProperty("win.frame.smallCaptionHeight", ncm.get_iSmCaptionHeight(), //$NON-NLS-1$
                       props);
        setIntProperty("win.menu.buttonWidth", ncm.get_iMenuWidth(), props); //$NON-NLS-1$
        setIntProperty("win.menu.height", ncm.get_iMenuHeight(), props);         //$NON-NLS-1$
    }

    private void getIconMetrics(Map<String, Object> props) {
        Win32.ICONMETRICSW im = win32.createICONMETRICSW(false);
        im.set_cbSize(im.size());
        win32.SystemParametersInfoW(WindowsDefs.SPI_GETICONMETRICS,
                                    im.size(), im.getElementPointer(0), 0);
        setFontProperty("win.icon.font", getFont(im.get_lfFont()), props); //$NON-NLS-1$
        setIntProperty("win.icon.hspacing", im.get_iHorzSpacing(), props); //$NON-NLS-1$
        setBoolProperty("win.icon.titleWrappingOn", im.get_iTitleWrap(), props); //$NON-NLS-1$
        setIntProperty("win.icon.vspacing", im.get_iVertSpacing(), props); //$NON-NLS-1$
    }

    private void getHighContrast(Map<String, Object> props) {
        Win32.HIGHCONTRASTA hc = win32.createHIGHCONTRASTA(false);
        hc.set_cbSize(hc.size());
        win32.SystemParametersInfoW(WindowsDefs.SPI_GETHIGHCONTRAST,
                                    hc.size(), hc.getElementPointer(0), 0);
        setBoolProperty("win.highContrast.on",  //$NON-NLS-1$
                        hc.get_dwFlags() & WindowsDefs.HCF_HIGHCONTRASTON,
                        props);
    }

    private void getSM(String propName, int idx, Map<String, Object> props) {
        setIntProperty(propName, win32.GetSystemMetrics(idx), props);
    }

    private int getIntSPI(int idx) {
        NativeBridge bridge = NativeBridge.getInstance();
        Int32Pointer ptr = bridge.createInt32Pointer(1, false);
        win32.SystemParametersInfoW(idx, 0, ptr, 0);
        return ptr.get(0);
    }

    private void getBoolSPI(String propName, int idx, Map<String, Object> props) {
        setBoolProperty(propName, getIntSPI(idx), props);
    }

    private void getIntSPI(String propName, int idx, Map<String, Object> props) {
        setIntProperty(propName, getIntSPI(idx), props);
    }

    void getXPTheme(Map<String, Object> props) {
        String style = "win.xpstyle."; //$NON-NLS-1$
        String nm = "Name"; //$NON-NLS-1$
        setBoolProperty(style + "themeActive", win32.IsThemeActive(), props);//$NON-NLS-1$
        int bufSize = 256;
        NativeBridge nb = NativeBridge.getInstance();
        Int16Pointer ptrs[] = new Int16Pointer[3];
        for (int i = 0; i < ptrs.length; i++) {
            ptrs[i] = nb.createInt16Pointer(bufSize, false);
        }
        String[] names = new String[] {"dll", "color", "size"};//$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
        int res = win32.GetCurrentThemeName(ptrs[0], bufSize, ptrs[1], bufSize,
                                            ptrs[2], bufSize);
        boolean ok = (res == WindowsDefs.S_OK);
        for (int i = 0; i < ptrs.length; i++) {
            String val = (ok ? ptrs[i].getString() : null);
            setDesktopProperty(style + names[i] + nm, val, props);
        }
    }

    private void getDnDProps(Map<String, Object> props) {
        String propName = "DnD"; //$NON-NLS-1$
        setIntProperty(propName + ".gestureMotionThreshold", //$NON-NLS-1$
                       WindowsDefs.DD_DEFDRAGMINDIST, props);
        propName += ".Autoscroll"; //$NON-NLS-1$
        setIntProperty(propName + ".initialDelay", //$NON-NLS-1$
                       WindowsDefs.DD_DEFSCROLLDELAY, props);
        setIntProperty(propName + ".interval", //$NON-NLS-1$
                       WindowsDefs.DD_DEFSCROLLINTERVAL, props);

    }

    private void getShellProps(Map<String, Object> props) {
        Win32.SHELLFLAGSTATE sfs = win32.createSHELLFLAGSTATE(false);
        int flags = (WindowsDefs.SSF_SHOWATTRIBCOL |
                     WindowsDefs.SSF_SHOWALLOBJECTS);
        win32.SHGetSettings(sfs, flags);
        String propName = "awt.file"; //$NON-NLS-1$
        setBoolProperty(propName + ".showAttribCol",  //$NON-NLS-1$
                        sfs.get_fShowAttribCol(), props);
        setBoolProperty(propName + ".showHiddenFiles",  //$NON-NLS-1$
                        (sfs.get_fShowAllObjects()), props);
    }

    private void getMouseProps(Map<String, Object> props) {
        String propName = "awt."; //$NON-NLS-1$
        getSM(propName + "mouse.numButtons", WindowsDefs.SM_CMOUSEBUTTONS, props); //$NON-NLS-1$
        setIntProperty(propName + "multiClickInterval",  //$NON-NLS-1$
                       win32.GetDoubleClickTime(), props);
        setBoolProperty(propName + "wheelMousePresent", //$NON-NLS-1$
                        win32.GetSystemMetrics(WindowsDefs.SM_MOUSEWHEELPRESENT),
                        props);
        getIntSPI(propName + "wheelScrollLines", //$NON-NLS-1$
                  WindowsDefs.SPI_GETWHEELSCROLLLINES, props);

    }

    private void setSoundProperty(String propName, String sndName, Map<String, Object> props) {
        String base = "win.sound."; //$NON-NLS-1$
        setDesktopProperty(base + propName, new WinPlaySound(sndName), props);
    }

    private void initSoundProps(Map<String, Object> props) {
        setSoundProperty("asterisk", "SystemAsterisk", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("close", "Close", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("default", ".Default", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("exclamation", "SystemExclamation", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("exit", "SystemExit", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("hand", "SystemHand", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("maximize", "Maximize", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("menuCommand", "MenuCommand", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("menuPopup", "MenuPopup", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("minimize", "Minimize", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("open", "Open", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("question", "SystemQuestion", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("restoreDown", "RestoreDown", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("restoreUp", "RestoreUp", props); //$NON-NLS-1$ //$NON-NLS-2$
        setSoundProperty("start", "SystemStart", props); //$NON-NLS-1$ //$NON-NLS-2$

    }

    @SuppressWarnings("unchecked")
    public void mapInputMethodHighlight(InputMethodHighlight highlight, Map<TextAttribute, ?> map) {
        Map<TextAttribute, Object> _map = (Map<TextAttribute, Object>)map;
        TextAttribute key = TextAttribute.INPUT_METHOD_UNDERLINE;
        boolean selected = highlight.isSelected();
        switch(highlight.getState()) {
        case InputMethodHighlight.RAW_TEXT:
            _map.put(key, selected ? TextAttribute.UNDERLINE_LOW_GRAY :
                TextAttribute.UNDERLINE_LOW_DOTTED);
            break;
        case InputMethodHighlight.CONVERTED_TEXT:
            _map.put(key, selected ? TextAttribute.UNDERLINE_LOW_ONE_PIXEL :
                TextAttribute.UNDERLINE_LOW_DOTTED);
            if (selected) {
                // maybe get colors from system properties?
                key = TextAttribute.BACKGROUND;
                _map.put(key, Color.white);
                key = TextAttribute.FOREGROUND;
                _map.put(key, new Color(0, 0, 128));
                key = TextAttribute.SWAP_COLORS;
                _map.put(key, TextAttribute.SWAP_COLORS_ON);
            }
            break;
        }
    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEngine;

namespace QFramework
{
    public static class PackageKitAssemblyCache
    {
        private static readonly Lazy<List<Assembly>> mCachedAssemblies = new Lazy<List<Assembly>>(() =>
        {
            var cachedAssemblies = new List<Assembly>();

            foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (assembly.FullName.StartsWith("QF") || assembly.FullName.Contains("Kit") ||
                    assembly.FullName.StartsWith("Assembly-CSharp"))
                {
                    if (!cachedAssemblies.Contains(assembly))
                    {
                        cachedAssemblies.Add(assembly);
                    }
                }
            }

            return cachedAssemblies;
        });

        public static IEnumerable<Type> GetAllTypes()
        {
            return mCachedAssemblies.Value.SelectMany(a => a.GetTypes());
        }

        public static IEnumerable<Type> GetDerivedTypes<T>(bool includeAbstract = false, bool includeBase = true)
        {
            var type = typeof(T);
            if (includeBase)
                yield return type;
            if (includeAbstract)
            {
                foreach (var t in mCachedAssemblies.Value.SelectMany(assembly => assembly
                             .GetTypes()
                             .Where(x => type.IsAssignableFrom(x))))
                {
                    yield return t;
                }
            }
            else
            {
                var items = new List<Type>();
                foreach (var assembly in mCachedAssemblies.Value)
                {
                    try
                    {
                        items.AddRange(assembly.GetTypes()
                            .Where(x => type.IsAssignableFrom(x) && !x.IsAbstract));
                    }
                    catch (Exception ex)
                    {
                        Debug.Log(ex.Message);
                    }
                }

                foreach (var item in items)
                    yield return item;
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
@interface PracticeViewController : QZSPViewController

@end


text:
from pyspark.mllib.recommendation import ALS
from numpy import array

# Load and parse the data
# data = sc.textFile("mllib/data/als/test.data")
data = sc.textFile("data.txt")
ratings = data.map(lambda line: array([float(x) for x in line.split('\t')]))

# Build the recommendation model using Alternating Least Squares
rank = 10
numIterations = 20
model = ALS.train(ratings, rank, numIterations)

# Evaluate the model on training data
testdata = ratings.map(lambda p: (int(p[0]), int(p[1])))
predictions = model.predictAll(testdata).map(lambda r: ((r[0], r[1]), r[2]))
ratesAndPreds = ratings.map(lambda r: ((r[0], r[1]), r[2])).join(predictions)
MSE = ratesAndPreds.map(lambda r: (r[1][0] - r[1][1])**2).reduce(lambda x, y: x + y)/ratesAndPreds.count()
print("Mean Squared Error = " + str(MSE))


text:
using System;
using Blaze.Randomization.Lab;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UnitTest.Randomization.Lab
{
    [TestClass]
    public class RandomNumbersTest
    {
        [TestMethod]
        public void GenerateByte_1()
        {
            for (var i = 0; i < 100; i++)
            {
                var x = RandomNumbers.GenerateByte();
                Console.WriteLine(x);
            }
        }

        [TestMethod]
        public void GenerateDouble_From0To1_1()
        {
            for (var i = 0; i < 100; i++)
            {
                var x = RandomNumbers.GenerateDouble_From0To1();
                Console.WriteLine($"{x:F3}");
                Assert.IsTrue(x >= 0);
                Assert.IsTrue(x < 1);
            }
        }
    }
}


text:
$installerUrl = "http://nuget.degdarwin.com/api/v2/package/dagent/1.0.0"
#$installerUrl = "file:///C:/T_/Packages/dagent.1.0.0.nupkg"
$tempPath = Join-Path $env:TEMP "dagent"
if (!(Test-Path $tempPath)) { [IO.Directory]::CreateDirectory($tempPath) }

# download the installer
$installerPath = Join-Path $tempPath "DagentInstaller.zip"
Write-Host "Downloading $installerUrl to $installerPath"
$downloader = new-object Net.WebClient
$downloader.DownloadFile($installerUrl, $installerPath)

# unzip the package
Write-Host "Extracting $installerPath to destination..."
$shellApplication = new-object -com shell.application
$zipPackage = $shellApplication.NameSpace($installerPath)
$destinationFolder = $shellApplication.NameSpace($tempPath)
$destinationFolder.CopyHere($zipPackage.Items(),0x10)
$toolsPath = Join-Path $tempPath "tools"

# call Dagent installer
$dagentInstallerPS1 = Join-Path $toolsPath "DagentInstaller.ps1"
Write-Host "Executing $dagentInstallerPS1..."
& $dagentInstallerPS1

# ensure dagent::bin in session path
#Write-Host "Ensuring Dagent is included in the session path"
#$dagentPath = [Environment]::GetEnvironmentVariable("DagentPath", [EnvironmentVariableTarget]::Machine)
#if ($dagentPath -ne $null) { $dagentBinPath = Join-Path $dagentPath "bin" } else { $dagentBinPath = Join-Path ${env:ProgramFiles} "Dagent\bin" }
#if ($($env:Path).ToLower().Contains($($dagentBinPath).ToLower()) -eq $false) { $env:Path = $env:Path; }


text:
static inline void increment_head(cbuf_s* buffer){
	(buffer->head)++;

	if(buffer->head > buffer->last){ //if the head overflows the buffer, wrap it around to the start
		buffer->head = buffer->first;
	}
}

static inline void decrement_head(cbuf_s* buffer){
	(buffer->head)--;

	if(buffer->head < buffer->first){ //if the head underflows the buffer, wrap it around to the end
		buffer->head = buffer->last;
	}
}

cbuf_s* cbuf_create(uint_t max_elements){
	size_t buffer_size = (sizeof(char) * max_elements);
	cbuf_s* buffer = (cbuf_s*) malloc(sizeof(cbuf_s) + buffer_size);
	buffer->first = (char*) ((size_t) buffer + sizeof(cbuf_s));
	buffer->head = buffer->first; //initially the head is at the start of the buffer
	buffer->last = (char*) ((size_t) buffer->first + buffer_size - 1);

	return buffer;
}

void cbuf_append(cbuf_s* buffer, char value){
	*(buffer->head) = value; //place the value in the head of the list

	increment_head(buffer);
}

void cbuf_pop(cbuf_s* buffer, char* destination, uint_t value_count){
	int d_index = 0; //position in the destination array
	decrement_head(buffer); //since the head marks the next element to be used, we need to rewind by one first

	for(; value_count > 0; value_count--){
		destination[d_index++] = *(buffer->head);
		decrement_head(buffer);
	}

	increment_head(buffer); //to compensate for the initial decrement
}

void cbuf_peek(cbuf_s* buffer, char* destination, uint_t value_count){
	char* orig_head = buffer->head; //store the head

	cbuf_pop(buffer, destination, value_count);

	buffer->head = orig_head; //restore the head
}

void cbuf_delete(cbuf_s* buffer){
	free(buffer);
}


text:
package org.apache.catalina.startup;

import java.io.File;
import java.util.Enumeration;

import org.apache.catalina.Context;
import org.apache.catalina.Host;
import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.util.StringManager;

/**
 * Startup event listener for a Host that configures Contexts (web
 * applications) for all defined "users" who have a web application in a
 * directory with the specified name in their home directories.  The context
 * path of each deployed application will be set to ~xxxxx, where
 * xxxxx is the username of the owning user for that web application
 *
 * @author Craig R. McClanahan
 *
 */

public final class UserConfig
    implements LifecycleListener {

    private static org.apache.juli.logging.Log log=
        org.apache.juli.logging.LogFactory.getLog( UserConfig.class );

    // ----------------------------------------------------- Instance Variables

    /**
     * The Java class name of the Context configuration class we should use.
     */
    private String configClass = "org.apache.catalina.startup.ContextConfig";

    /**
     * The Java class name of the Context implementation we should use.
     */
    private String contextClass = "org.apache.catalina.core.StandardContext";

    /**
     * The directory name to be searched for within each user home directory.
     */
    private String directoryName = "public_html";

    /**
     * The base directory containing user home directories.
     */
    private String homeBase = null;

    /**
     * The Host we are associated with.
     */
    private Host host = null;

    /**
     * The string resources for this package.
     */
    private static final StringManager sm =
        StringManager.getManager(Constants.Package);

    /**
     * The Java class name of the user database class we should use.
     */
    private String userClass =
        "org.apache.catalina.startup.PasswdUserDatabase";

    // ------------------------------------------------------------- Properties

    /**
     * Return the Context configuration class name.
     */
    public String getConfigClass() {

        return (this.configClass);

    }

    /**
     * Set the Context configuration class name.
     *
     * @param configClass The new Context configuration class name.
     */
    public void setConfigClass(String configClass) {

        this.configClass = configClass;

    }

    /**
     * Return the Context implementation class name.
     */
    public String getContextClass() {

        return (this.contextClass);

    }

    /**
     * Set the Context implementation class name.
     *
     * @param contextClass The new Context implementation class name.
     */
    public void setContextClass(String contextClass) {

        this.contextClass = contextClass;

    }

    /**
     * Return the directory name for user web applications.
     */
    public String getDirectoryName() {

        return (this.directoryName);

    }

    /**
     * Set the directory name for user web applications.
     *
     * @param directoryName The new directory name
     */
    public void setDirectoryName(String directoryName) {

        this.directoryName = directoryName;

    }

    /**
     * Return the base directory containing user home directories.
     */
    public String getHomeBase() {

        return (this.homeBase);

    }

    /**
     * Set the base directory containing user home directories.
     *
     * @param homeBase The new base directory
     */
    public void setHomeBase(String homeBase) {

        this.homeBase = homeBase;

    }

    /**
     * Return the user database class name for this component.
     */
    public String getUserClass() {

        return (this.userClass);

    }

    /**
     * Set the user database class name for this component.
     */
    public void setUserClass(String userClass) {

        this.userClass = userClass;

    }

    // --------------------------------------------------------- Public Methods

    /**
     * Process the START event for an associated Host.
     *
     * @param event The lifecycle event that has occurred
     */
    public void lifecycleEvent(LifecycleEvent event) {

        // Identify the host we are associated with
        try {
            host = (Host) event.getLifecycle();
        } catch (ClassCastException e) {
            log.error(sm.getString("hostConfig.cce", event.getLifecycle()), e);
            return;
        }

        // Process the event that has occurred
        if (event.getType().equals(Lifecycle.START_EVENT))
            start();
        else if (event.getType().equals(Lifecycle.STOP_EVENT))
            stop();

    }

    // -------------------------------------------------------- Private Methods

    /**
     * Deploy a web application for any user who has a web application present
     * in a directory with a specified name within their home directory.
     */
    private void deploy() {

        if (host.getLogger().isDebugEnabled())
            host.getLogger().debug(sm.getString("userConfig.deploying"));

        // Load the user database object for this host
        UserDatabase database = null;
        try {
            Class clazz = Class.forName(userClass);
            database = (UserDatabase) clazz.newInstance();
            database.setUserConfig(this);
        } catch (Exception e) {
            host.getLogger().error(sm.getString("userConfig.database"), e);
            return;
        }

        // Deploy the web application (if any) for each defined user
        Enumeration users = database.getUsers();
        while (users.hasMoreElements()) {
            String user = (String) users.nextElement();
            String home = database.getHome(user);
            deploy(user, home);
        }

    }

    /**
     * Deploy a web application for the specified user if they have such an
     * application in the defined directory within their home directory.
     *
     * @param user Username owning the application to be deployed
     * @param home Home directory of this user
     */
    private void deploy(String user, String home) {

        // Does this user have a web application to be deployed?
        String contextPath = "/~" + user;
        if (host.findChild(contextPath) != null)
            return;
        File app = new File(home, directoryName);
        if (!app.exists() || !app.isDirectory())
            return;
        /*
        File dd = new File(app, "/WEB-INF/web.xml");
        if (!dd.exists() || !dd.isFile() || !dd.canRead())
            return;
        */
        host.getLogger().info(sm.getString("userConfig.deploy", user));

        // Deploy the web application for this user
        try {
            Class clazz = Class.forName(contextClass);
            Context context =
              (Context) clazz.newInstance();
            context.setPath(contextPath);
            context.setDocBase(app.toString());
            if (context instanceof Lifecycle) {
                clazz = Class.forName(configClass);
                LifecycleListener listener =
                  (LifecycleListener) clazz.newInstance();
                ((Lifecycle) context).addLifecycleListener(listener);
            }
            host.addChild(context);
        } catch (Exception e) {
            host.getLogger().error(sm.getString("userConfig.error", user), e);
        }

    }

    /**
     * Process a "start" event for this Host.
     */
    private void start() {

        if (host.getLogger().isDebugEnabled())
            host.getLogger().debug(sm.getString("userConfig.start"));

        deploy();

    }

    /**
     * Process a "stop" event for this Host.
     */
    private void stop() {

        if (host.getLogger().isDebugEnabled())
            host.getLogger().debug(sm.getString("userConfig.stop"));

    }

}


text:
/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/secureboot/node_comm/node_comm_exchange_helper.C $    */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2021                             */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/**
 * @file  node_comm_exchange_helper.C
 * @brief Contains the implementations of the node comm helper functions and
 *        classes.
 */

#include "node_comm_exchange_helper.H"
#include "node_comm_transfer.H"
#include <secureboot/secure_reasoncodes.H>
#include <sys/time.h>
#include <isteps/istepHelperFuncs.H>
#include <secureboot/trustedbootif.H>

namespace SECUREBOOT
{

namespace NODECOMM
{

mutex_t NodeCommExchangeQuotes::iv_quoteMutex = MUTEX_INITIALIZER;
mutex_t NodeCommExchange::iv_errorMutex = MUTEX_INITIALIZER;

/**
 * @brief Helper function to capture an error safely
 *
 * @param[in] i_errl the error to capture
 */
void NodeCommExchange::handleError(errlHndl_t i_errl)
{
    errlHndl_t l_poisonTpmErr = TRUSTEDBOOT::poisonAllTpms();
    if(l_poisonTpmErr)
    {
        if(i_errl)
        {
            l_poisonTpmErr->plid(i_errl->plid());
        }
        TRACFCOMP(g_trac_nc,ERR_MRK"NodeCommExchange::handleError(): Could not poison TPMs");
        if(!TRUSTEDBOOT::isTpmRequired())
        {
            TRACFCOMP(g_trac_nc,ERR_MRK"NodeCommExchange::handleError(): TPM is not required, setting errl EID 0x%x to Informational",
                      l_poisonTpmErr->eid());
            l_poisonTpmErr->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
        }
        errlCommit(l_poisonTpmErr, SECURE_COMP_ID);
    }

    mutex_lock(&iv_errorMutex);
    if(!TRUSTEDBOOT::isTpmRequired())
    {
        TRACFCOMP(g_trac_nc,INFO_MRK"NodeCommExchange::handleError(): TPM is not required; changing the severity of error 0x%x to INFORMATIONAL",
                  i_errl->eid());
        i_errl->setSev(ERRORLOG::ERRL_SEV_INFORMATIONAL);
        // Don't propagate informational errors to istep
        errlCommit(i_errl, SECURE_COMP_ID);
    }
    else
    {
        captureError(i_errl, *iv_istepError, SECURE_COMP_ID);
    }
    mutex_unlock(&iv_errorMutex);
}

/**
 * @brief Helper function to get the link and mailbox IDs for this node
 *        and the peer node from the IOHS info provided.
 *
 * @param[in] i_iohsInstance the IOHS info of the current node and the
 *            peer
 * @param[out] o_myLinkId the resulting link ID of the current node
 * @param[out] o_myMboxId the resulting mailbox ID of the current node
 * @param[out] o_peerLinkId the resulting link ID of the peer node
 * @param[out] o_peerMboxId the resulting mailbox ID of the peer node
 */
void getLinkMboxInfo(const iohs_instances_t& i_iohsInstance,
                     uint8_t& o_myLinkId, uint8_t& o_myMboxId,
                     uint8_t& o_peerLinkId, uint8_t& o_peerMboxId)
{
    // Get the link and mbox ID for the current node
    getLinkMboxFromIohsInstance(i_iohsInstance.myIohsInstance,
                                i_iohsInstance.myIohsRelLink,
                                o_myLinkId,
                                o_myMboxId);

    // Get the link and mbox ID for the peer node
    getLinkMboxFromIohsInstance(i_iohsInstance.peerIohsInstance,
                                // same relative link for peer path:
                                i_iohsInstance.myIohsRelLink,
                                o_peerLinkId,
                                o_peerMboxId);
}

/**
 * @brief Sends a nonce (8-byte random number) to the peer node
 *        of the current node as defined by the IOHS link info.
 *
 * @param[in] i_iohsInstance the IOHS info of the current and peer nodes
 * @param[in] i_nonce the 8-byte nonce to send to the peer node
 * @return nullptr on success; non-nullptr on error
 */
errlHndl_t sendNonceToPeer(const iohs_instances_t& i_iohsInstance,
                           const uint64_t& i_nonce)
{
    errlHndl_t l_errl = nullptr;
    uint8_t l_myLinkId = 0;
    uint8_t l_myMboxId = 0;
    uint8_t l_expectedPeerLinkId = 0;
    uint8_t l_expectedPeerMboxId = 0;

    // Get this node and peer's link and mbox info
    getLinkMboxInfo(i_iohsInstance, l_myLinkId, l_myMboxId,
                    l_expectedPeerLinkId, l_expectedPeerMboxId);

    TRACFCOMP(g_trac_nc,INFO_MRK"sendNonceToPeer: "
              "my: linkId=%d, mboxId=%d, IohsInstance=%d. "
              "expected peer: n%d linkId=%d, mboxId=%d, IohsInstance=%d",
              l_myLinkId, l_myMboxId, i_iohsInstance.myIohsInstance,
              i_iohsInstance.peerNodeInstance, l_expectedPeerLinkId,
              l_expectedPeerMboxId, i_iohsInstance.peerIohsInstance);

    // Message data to contain the nonce
    msg_format_t l_msgData;
    l_msgData.value = i_nonce;
    size_t l_msgSize = sizeof(l_msgData.value);

    // The node comm control and data regs live on PAUC parents of IOHS
    TARGETING::Target* l_paucParent =
           TARGETING::getImmediateParentByAffinity(i_iohsInstance.myIohsTarget);

    // Send the message
    l_errl = nodeCommTransferSend(l_paucParent,
                                  l_myLinkId,
                                  l_myMboxId,
                                  i_iohsInstance.peerNodeInstance,
                                  NCT_TRANSFER_SBID,
                                  reinterpret_cast<uint8_t*>(&(l_msgData.value)),
                                  l_msgSize);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"sendNonceToPeer: Could not send message to the peer node %d",
                  i_iohsInstance.peerNodeInstance);
    }

    return l_errl;
}

/**
 * @brief Receives a nonce (8-byte random number) from the peer node
 *        of the current node as defined by the IOHS link info
 *
 * @param[in] i_iohsInstance the IOHS info of the current and peer nodes
 * @param[out] o_nonce the 8-byte nonce received from the peer node (0 in case
 *             of an error)
 * @return nullptr on success; non-nullptr on error
 */
errlHndl_t receiveNonceFromPeer(const iohs_instances_t& i_iohsInstance,
                                uint64_t& o_nonce)
{
    errlHndl_t l_errl = nullptr;
    // Pointer to buffer used for receiving data from nodeCommTransferRecv()
    uint8_t * l_dataRcvBuffer = nullptr;
    uint8_t l_myLinkId = 0;
    uint8_t l_myMboxId = 0;
    uint8_t l_expectedPeerLinkId = 0;
    uint8_t l_expectedPeerMboxId = 0;

    // Get this node and peer's link and mbox info
    getLinkMboxInfo(i_iohsInstance, l_myLinkId, l_myMboxId,
                    l_expectedPeerLinkId, l_expectedPeerMboxId);

    TRACFCOMP(g_trac_nc,INFO_MRK"receiveNonceFromPeer: "
              "my: linkId=%d, mboxId=%d, IohsInstance=%d. "
              "expected peer: n%d linkId=%d, mboxId=%d, IohsInstance=%d",
              l_myLinkId, l_myMboxId, i_iohsInstance.myIohsInstance,
              i_iohsInstance.peerNodeInstance, l_expectedPeerLinkId,
              l_expectedPeerMboxId, i_iohsInstance.peerIohsInstance);

    // The node comm control and data regs live on PAUC parents of IOHS
    TARGETING::Target* l_paucParent =
           TARGETING::getImmediateParentByAffinity(i_iohsInstance.myIohsTarget);
    size_t l_msgSize = sizeof(o_nonce);
    l_errl = nodeCommTransferRecv(l_paucParent,
                                  l_myLinkId,
                                  l_myMboxId,
                                  i_iohsInstance.peerNodeInstance,
                                  NCT_TRANSFER_SBID,
                                  l_dataRcvBuffer,
                                  l_msgSize);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"receiveNonceFromPeer: Could not get nonce from peer node %d",
                  i_iohsInstance.peerNodeInstance);
        o_nonce = NODE_COMM_DEFAULT_NONCE;
    }
    else
    {
        // If no err is returned, l_dataRcvBuffer should be valid, but do a
        // sanity check here to be certain
        assert(l_dataRcvBuffer!=nullptr,"receiveNonceFromPeer: l_dataRcvBuffer returned as nullptr");
        memcpy(&o_nonce, l_dataRcvBuffer, l_msgSize);
    }
    return l_errl;
}

/**
 * @brief Performs nonce exchange between two nodes as defined by internal iv_iohsInstance
 *        variable. If the current node's ID is lower than the peer's, then the current node
 *        will send its nonce first, and the peer node will receive the nonce first. Then
 *        the order reverses.
 */
void NodeCommExchangeNonces::operator()()
{
    errlHndl_t l_errl = nullptr;

    // Create a msg_format_t structure so that we can populate the link and node
    // info into the nonce later.
    msg_format_t l_myNonce, l_peerNonce;
    l_myNonce.value = 0;
    l_peerNonce.value = 0;

    TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeNonces: This thread from node %d to node %d",
              iv_iohsInstance.myNodeInstance, iv_iohsInstance.peerNodeInstance);

    l_errl = nodeCommGetRandom(l_myNonce.value);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"NodeCommExchangeNonces: could not get nonce from the TPM");
        // Commit error and continue to prevent deadlocks
        handleError(l_errl);
        l_myNonce.value = NODE_COMM_DEFAULT_NONCE;
    }
    else
    {
        uint8_t l_mboxIdUnused = 0;
        uint8_t l_myLinkId = 0;
        uint8_t l_peerLinkId = 0;

        // Incorporate our link ID and the link ID of the receiver into the nonce
        getLinkMboxInfo(iv_iohsInstance,
                        l_myLinkId, l_mboxIdUnused,
                        l_peerLinkId, l_mboxIdUnused);

        l_myNonce.origin_linkId = l_myLinkId;
        l_myNonce.receiver_linkId = l_peerLinkId;
    }

    // Node with lower position sends nonce first and then receives response,
    // while node with higher position receives the nonce first, and then
    // sends its nonce in response.
    if(iv_iohsInstance.myNodeInstance < iv_iohsInstance.peerNodeInstance)
    {
        TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeNonces This node (%d) will send nonce first to node %d",
                  iv_iohsInstance.myNodeInstance, iv_iohsInstance.peerNodeInstance);
        l_errl = sendNonceToPeer(iv_iohsInstance, l_myNonce.value);
        if(l_errl)
        {
            TRACFCOMP(g_trac_nc, ERR_MRK"NodeCommExchangeNonces: Could not send nonce to peer node %d"
                      TRACE_ERR_FMT, iv_iohsInstance.peerNodeInstance,
                      TRACE_ERR_ARGS(l_errl));
            // Commit the error so that we can continue the exchange and prevent
            // deadlocks.
            handleError(l_errl);
        }

        // Wait 100ms to make sure that the other node had a chance to proces
        // the message ack from the previous transaction before requesting a
        // new exchange.
        nanosleep(0, 100*NS_PER_MSEC);

        l_errl = receiveNonceFromPeer(iv_iohsInstance, l_peerNonce.value);

        if(l_errl)
        {
            TRACFCOMP(g_trac_nc, ERR_MRK"NodeCommExchangeNonces: Could not receive nonce from peer node %d"
                      TRACE_ERR_FMT, iv_iohsInstance.peerNodeInstance,
                      TRACE_ERR_ARGS(l_errl));
            // Commit the error so that we can continue the exchange and prevent
            // deadlocks.
            handleError(l_errl);
        }
    }
    else
    {
        TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeNonces This node (%d) will receive nonce first from node %d",
                  iv_iohsInstance.myNodeInstance, iv_iohsInstance.peerNodeInstance);
        l_errl = receiveNonceFromPeer(iv_iohsInstance, l_peerNonce.value);
        if(l_errl)
        {
            TRACFCOMP(g_trac_nc, ERR_MRK"NodeCommExchangeNonces: Could not receive nonce from peer node %d"
                      TRACE_ERR_FMT, iv_iohsInstance.peerNodeInstance,
                      TRACE_ERR_ARGS(l_errl));
            // Commit the error so that we can continue the exchange and prevent
            // deadlocks.
            handleError(l_errl);
        }

        // Wait 100ms to make sure that the other node had a chance to proces
        // the message ack from the previous transaction before requesting a
        // new exchange.
        nanosleep(0, 100*NS_PER_MSEC);

        TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeNonces This node (%d) will now send nonce 0x%x to node %d",
                  iv_iohsInstance.myNodeInstance, l_myNonce.value, iv_iohsInstance.peerNodeInstance);
        l_errl = sendNonceToPeer(iv_iohsInstance, l_myNonce.value);
        if(l_errl)
        {
            TRACFCOMP(g_trac_nc, ERR_MRK"NodeCommExchangeNonces: Could not send nonce to peer node %d"
                      TRACE_ERR_FMT, iv_iohsInstance.peerNodeInstance,
                      TRACE_ERR_ARGS(l_errl));
            // Commit the error so that we can continue the exchange and prevent
            // deadlocks.
            handleError(l_errl);
        }
    }

    l_errl = nodeCommLogNonce(l_myNonce.value);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"NodeCommExchangeNonces: Could not extend this node's nonce into TPM");
        handleError(l_errl);
    }

    l_errl = nodeCommLogNonce(l_peerNonce.value);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"NodeCommExchangeNonces: Could not extend node %d nonce into TPM",
                  iv_iohsInstance.peerNodeInstance);
        handleError(l_errl);
    }
}

/**
 * @brief Helper function to generate a quote request from the peer node, send the quote request to
 *        that node, and receive a quote from the node.
 *
 * @param[in] i_iohsInstance the IOHS information of the peer node
 * @param[out] o_quote the node quote in binary format (received from the peer node)
 * @param[out] o_quoteSize the size of the node quote in bytes
 * @return nullptr on success; non-nullptr on error
 */
errlHndl_t requestQuote(const iohs_instances_t& i_iohsInstance, uint8_t*& o_quote, size_t& o_quoteSize)
{
    errlHndl_t l_errl = nullptr;

    do {
    // Generate quote request
    QuoteRequestBlob l_quoteRequest{};
    l_errl = nodeCommGenQuoteRequest(&l_quoteRequest);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"requestQuote: Could not generate quote request"
                  TRACE_ERR_FMT, TRACE_ERR_ARGS(l_errl));
        break;
    }

    // Send the quote request
    // The node comm control and data regs live on PAUC parents of IOHS
    TARGETING::Target* l_paucParent =
            TARGETING::getImmediateParentByAffinity(i_iohsInstance.myIohsTarget);
    uint8_t l_myLinkId = 0;
    uint8_t l_myMboxId = 0;

    getLinkMboxFromIohsInstance(i_iohsInstance.myIohsInstance,
                                i_iohsInstance.myIohsRelLink,
                                l_myLinkId,
                                l_myMboxId);

    size_t l_quoteRequestSize = sizeof(l_quoteRequest);
    l_errl = nodeCommTransferSend(l_paucParent,
                                  l_myLinkId,
                                  l_myMboxId,
                                  i_iohsInstance.peerNodeInstance,
                                  NCT_TRANSFER_QUOTE_REQUEST,
                                  reinterpret_cast<uint8_t*>(&l_quoteRequest),
                                  l_quoteRequestSize);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"requestQuote: Could not send quote to peer node %d"
                  TRACE_ERR_FMT, i_iohsInstance.peerNodeInstance, TRACE_ERR_ARGS(l_errl));
        break;
    }

    // Get the response (quote) from the other node
    l_errl = nodeCommTransferRecv(l_paucParent,
                                  l_myLinkId,
                                  l_myMboxId,
                                  i_iohsInstance.peerNodeInstance,
                                  NCT_TRANSFER_QUOTE_RESPONSE,
                                  o_quote,
                                  o_quoteSize);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"requestQuote: Cound not receive response from node %d"
                  TRACE_ERR_FMT, i_iohsInstance.peerNodeInstance, TRACE_ERR_ARGS(l_errl));
        break;
    }

    assert(o_quote, "requestQuote: Response buffer is nullptr!");

    NCEyeCatcher_t* l_eyeCatcher =
        reinterpret_cast<NCEyeCatcher_t*>(o_quote);
    uint32_t* l_peerNodeId = reinterpret_cast<uint32_t*>(o_quote + sizeof(*l_eyeCatcher));

    // Check if the peer node had any TPM issues
    if(*l_eyeCatcher == NDNOTPM_)
    {
        /*@
         * @errortype
         * @reasoncode RC_NC_BAD_QUOTE
         * @moduleid   MOD_NCT_REQUEST_QUOTE
         * @userdata1  Peer node ID
         * @devdesc    Peer node indicated that it encountered an issue during
         *             secure node comm.
         * @custdesc   trustedboot failure
         */
        l_errl = new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE,
                                         MOD_NCT_REQUEST_QUOTE,
                                         RC_NC_BAD_QUOTE,
                                         *l_peerNodeId,
                                         0,
                                         ERRORLOG::ErrlEntry::ADD_SW_CALLOUT);
        l_errl->collectTrace(SECURE_COMP_NAME);
        l_errl->collectTrace(TRBOOT_COMP_NAME);
        l_errl->collectTrace(NODECOMM_TRACE_NAME);
        break;
    }

    }while(0);
    return l_errl;
}

/**
 * @brief A helper function to look for a quote request from the peer node, generate the
 *        node quote, and send the quote to the peer node.
 *
 * @param[in] i_iohsInstance IOHS information of the peer node.
 * @return nullptr on success; non-nullptr on error
 */
errlHndl_t sendQuote(const iohs_instances_t& i_iohsInstance)
{
    errlHndl_t l_errl = nullptr;
    uint8_t* l_dataBuffer = nullptr;
    size_t l_dataSize = 0;

    do {
    uint8_t l_myLinkId = 0;
    uint8_t l_myMboxId = 0;
    getLinkMboxFromIohsInstance(i_iohsInstance.myIohsInstance,
                                i_iohsInstance.myIohsRelLink,
                                l_myLinkId,
                                l_myMboxId);
    // The node comm control and data regs live on PAUC parents of IOHS
    TARGETING::Target* l_paucParent =
           TARGETING::getImmediateParentByAffinity(i_iohsInstance.myIohsTarget);

    // Wait for a request from peer
    l_errl = nodeCommTransferRecv(l_paucParent,
                                  l_myLinkId,
                                  l_myMboxId,
                                  i_iohsInstance.peerNodeInstance,
                                  NCT_TRANSFER_QUOTE_REQUEST,
                                  l_dataBuffer,
                                  l_dataSize);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"sendQuote: Could not receive quote request from peer node %d"
                  TRACE_ERR_FMT, i_iohsInstance.peerNodeInstance, TRACE_ERR_ARGS(l_errl));
        break;
    }

    // Make a quote request out of the received data
    QuoteRequestBlob l_quoteRequest{};
    memcpy(&l_quoteRequest, l_dataBuffer, l_dataSize);

    // Re-use the data buffer for the response quote
    free(l_dataBuffer);
    l_dataBuffer = nullptr;

    std::unique_ptr<uint8_t>l_quotePtr = nullptr;

    // Generate a response
    l_errl = nodeCommGenQuoteResponse(&l_quoteRequest,
                                      l_dataSize,
                                      l_quotePtr);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"sendQuote: Could not generate quote to respond to node %d"
                  TRACE_ERR_FMT, i_iohsInstance.peerNodeInstance, TRACE_ERR_ARGS(l_errl));
        break;
    }

    // Send the quote to the peer node
    l_errl = nodeCommTransferSend(l_paucParent,
                                  l_myLinkId,
                                  l_myMboxId,
                                  i_iohsInstance.peerNodeInstance,
                                  NCT_TRANSFER_QUOTE_RESPONSE,
                                  l_quotePtr.get(),
                                  l_dataSize);
    if(l_errl)
    {
        TRACFCOMP(g_trac_nc, ERR_MRK"sendQuote: Could not send the quote to peer node %d"
                  TRACE_ERR_FMT, i_iohsInstance.peerNodeInstance, TRACE_ERR_ARGS(l_errl));
        break;
    }

    }while(0);

    return l_errl;
}

/**
 * @brief Perform quote exchange between the nodes on the system. Each node, when communicating with
 *        another node, will act as a requestor once and as a responder once, so in any given system,
 *        each node will send its quote to every other node and will receive quotes from every other
 *        node. If the current node is a lower node ID, it will request the quote first, and then
 *        send its quote to the peer. Otherwise, the opposite happens.
 */
void NodeCommExchangeQuotes::operator()()
{
    errlHndl_t l_errl = nullptr;
    uint8_t* l_data = nullptr;
    size_t l_dataSize = 0;

    do {

    // Node with lower position requests the quote first and then waits for quote request
    // from the peer node, while node with higher position does the procedure in reverse.
    if(iv_iohsInstance.myNodeInstance < iv_iohsInstance.peerNodeInstance)
    {
        TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeQuotes: This node will request the quote first from node %d",
                  iv_iohsInstance.peerNodeInstance);
        // Request a quote from the peer node
        l_errl = requestQuote(iv_iohsInstance, l_data, l_dataSize);
        if(l_errl)
        {
            // Capture and continue communicating
            handleError(l_errl);
        }

        // Wait 10ms before sending the quote to make sure the communication protocol
        // has a chance to catch up.
        nanosleep(0, 10*NS_PER_MSEC);

        TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeQuotes: This node will now wait for a request from node %d",
                  iv_iohsInstance.peerNodeInstance);
        // Wait for a quote request from the peer node
        l_errl = sendQuote(iv_iohsInstance);
        if(l_errl)
        {
            // Capture and continue communicating
            handleError(l_errl);
        }
    }
    else
    {
        TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeQuotes: This node will first wait for a request from node %d",
                  iv_iohsInstance.peerNodeInstance);
        // Look for a request from the peer node
        l_errl = sendQuote(iv_iohsInstance);
        if(l_errl)
        {
            // Capture and continue communicating
            handleError(l_errl);
        }

        // Wait 10ms before sending the quote to make sure the communication protocol
        // has a chance to catch up.
        nanosleep(0, 10*NS_PER_MSEC);

        // Now request a quote from the peer node
        TRACFCOMP(g_trac_nc, INFO_MRK"NodeCommExchangeQuotes: This node will now request the quote from node %d",
                  iv_iohsInstance.peerNodeInstance);
        l_errl = requestQuote(iv_iohsInstance, l_data, l_dataSize);
        if(l_errl)
        {
            // Capture and continue communicating
            handleError(l_errl);
        }
    }

    // Grab the quote mutex
    mutex_lock(&iv_quoteMutex);
    // Add the recieved quote to the list
    quoteInfo_t l_quoteInfo {};
    l_quoteInfo.quoteData = new uint8_t[l_dataSize];
    l_quoteInfo.quoteSize = l_dataSize;
    memcpy(l_quoteInfo.quoteData, l_data, l_dataSize);
    iv_quotes->push_back(l_quoteInfo);
    mutex_unlock(&iv_quoteMutex);

    TRACDBIN(g_trac_nc, "Quote received:", l_data, l_dataSize);
    } while(0);

    free(l_data);
    l_data = nullptr;
}

} // namespace NODECOMM
} // namespace SECUREBOOT