content: package utils;
  
  import java.awt.AWTKeyStroke;
  import java.awt.Component;
  import java.awt.Font;
  import java.awt.GraphicsConfiguration;
  import java.awt.GraphicsDevice;
  import java.awt.GraphicsEnvironment;
  import java.awt.Toolkit;
  import java.awt.event.InputEvent;
  import java.awt.event.KeyEvent;
  import java.awt.geom.AffineTransform;
  import java.lang.reflect.Field;
  import java.lang.reflect.Method;
  
  import javax.swing.JComponent;
  import javax.swing.JPopupMenu;
  import javax.swing.JSeparator;
  import javax.swing.KeyStroke;
  import javax.swing.LookAndFeel;
  import javax.swing.UIManager;
  
  import org.apache.commons.lang.StringUtils;
  import org.apache.log4j.Logger;
  import org.simplericity.macify.eawt.Application;
  import org.simplericity.macify.eawt.DefaultApplication;
  
  import aliview.AliView;
  
  public class OSNativeUtils {
  	private static final Logger logger = Logger.getLogger(OSNativeUtils.class);
  	// private static float contentScaleFactor = -1; // 1 indicates a regular mac display. 2= retina
  
  	public static void main(String[] args) {
  		double version = getJavaVersionAsDouble();
  		logger.info("version=" + version);
  	}
  
  	public static boolean isWindows() {
  
  		String os = System.getProperty("os.name").toLowerCase();
  		// windows
  		return (os.indexOf("win") >= 0);
  
  	}
  	
  	/*
  	 * 
  	 * TODO Fix this so that you can move window from HighDPI to normal and vice.v.
  	 * https://stackoverflow.com/questions/20767708/how-do-you-detect-a-retina-display-in-java
  	 * 
  	 */
  	public static double getHighDPIScaleFactor(Component component) {
  		
  		// 1 indicates a regular mac display. 2= retina
  		double scaleFactor = -1;
  		if(isJavaVersion8orLower()) {
  		
  			//Just call all methods and see which returns highest value
  			double scaleFactorJ6 = getHighDPIScaleFactor_OSX_Java6();
  			logger.info("scaleFactorJ6" + scaleFactorJ6);
  			double scaleFactorJ8 = getHighDPIScaleFactor_OSX_Java_Pre_9(component);
  			logger.info("scaleFactorJ8" + scaleFactorJ8);
  			
  			scaleFactor = Math.max(scaleFactorJ6, scaleFactorJ8);		
  		}
  		else {
  			scaleFactor = getHighDPIScaleFactor_OSX_Java_9_or_Later(component);
  		}
  		
  		// Set 1 as minimum
  		if(scaleFactor == -1){
  			scaleFactor = 1;
  		}
  		
  		return scaleFactor;
  		
  	}
  
  	public static float getHighDPIScaleFactor_OSX_Java6() {
  		    float scaleFactor = -1;
  			Object obj = Toolkit.getDefaultToolkit().getDesktopProperty("apple.awt.contentScaleFactor");
  			if (obj instanceof Float) {
  				Float f = (Float) obj;
  				scaleFactor = f;
  			}		
  			return scaleFactor;
  	}
  	
  	private static double getHighDPIScaleFactor_OSX_Java_Pre_9(final Component component) {
  		double scaleFactor = -1;
          final GraphicsDevice device = getCurrentDevice(component);
          try {
          	// Try to call scale factor method (if it is not on OSX device a reflection exception will be thrown)
              final Method getScaleFactorMethod = device.getClass().getMethod("getScaleFactor");
              final Object scale = getScaleFactorMethod.invoke(device);
              if (scale instanceof Integer) {
              	Integer intScale = (Integer) scale;
              	scaleFactor = intScale.intValue();
  	        }
          } catch (Error err) {
          	logger.debug("Reflection error? " + err);
              return -1;
          } catch (Exception e) {
          	logger.debug("Reflection exception? " + e);
              return -1;
          }
          return scaleFactor;
      }
  	
  	private static double getHighDPIScaleFactor_OSX_Java_9_or_Later(final Component component) {
          return getCurrentConfiguration(component).getDefaultTransform().getScaleX();
      }
  	
  	private static GraphicsConfiguration getCurrentConfiguration(final Component component) {
          final GraphicsConfiguration graphicsConfiguration = component.getGraphicsConfiguration();
          if (graphicsConfiguration == null) {
              return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
          } else {
              return graphicsConfiguration;
          }
      }
  	
      private static GraphicsDevice getCurrentDevice(final Component component) {
          final GraphicsConfiguration graphicsConfiguration = component.getGraphicsConfiguration();
          if (graphicsConfiguration == null) {
              return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
          } else {
              return graphicsConfiguration.getDevice();
          }
      }
  
  	public static boolean isRunningDefectJFilechooserJVM(){
  		logger.info("java ver" + getJavaVersionAsDouble());	
  		String javaVersion = System.getProperty("java.version").toLowerCase();
  		if(isWindows() && getJavaVersionAsDouble() >= 7 && getJavaVersionAsDouble() < 8){
  			return true;
  		}
  		return false;
  	}
  
  	/*
  	 * 
  	 * 1.6.0_25 is returned as 6.25
  	 * 
  	 */
  	private static double getJavaVersionAsDouble(){
  		double version = 0;
  		try{	
  			// java version "";
  			String javaVersion = System.getProperty("java.version").toLowerCase();
  
  			logger.info("javaVersion" + javaVersion);
  
  			String[] splitted = StringUtils.split(javaVersion,"._-");
  
  			String major = "";
  			String minor = "";
  			if(splitted[0].equals("1")){
  				major = splitted[1];
  				minor = splitted[3];
  			}else{
  				major = splitted[0];
  				minor = splitted[2];
  			}
  
  			String versionString = major + "." + minor;
  			version = Double.parseDouble(versionString);
  
  		}catch(Exception e){
  			e.printStackTrace();
  		}
  		return version;
  	}
  
  	private static boolean isJavaVersion8orLower() {
  		double javaVersion = getJavaVersionAsDouble();
  		logger.info("java_version=" + javaVersion);
  
  		if(javaVersion < 9){
  			return true;
  		}
  		else{
  			return false;
  		}
  	}
  
  	public static boolean isMac() {
  
  		String os = System.getProperty("os.name").toLowerCase();
  		// Mac
  		return (os.indexOf("mac") >= 0);
  
  	}
  
  	public static boolean isAnythingButMac() {
  		return ! isMac();
  	}
  
  	public static boolean isLinuxOrUnix() {
  
  		String os = System.getProperty("os.name").toLowerCase();
  		// linux or unix
  		return (os.indexOf("nix") >= 0 || os.indexOf("nux") >= 0);
  
  	}
  
  	public static boolean isSolaris() {
  
  		String os = System.getProperty("os.name").toLowerCase();
  		// Solaris
  		return (os.indexOf("sunos") >= 0);
  
  	}
  
  	public static boolean is32BitOS() { 
  		String os = System.getProperty("os.arch").toLowerCase();
  		return (os.indexOf("32") >= 0);
  	}
  
  	public static boolean is64BitOS() { 
  		String os = System.getProperty("os.arch").toLowerCase();
  		return (os.indexOf("64") >= 0);
  	}
  
  	public static boolean isPowerPC() { 
  		String os = System.getProperty("os.arch").toLowerCase();
  		return (os.indexOf("powerpc") >= 0);
  	}
  
  
  	public static KeyStroke getReloadKeyAccelerator() {
  		return KeyStroke.getKeyStroke(KeyEvent.VK_R, InputEvent.CTRL_DOWN_MASK);
  	}
  
  	public static KeyStroke getCopySelectionAsFastaKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getCopyKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.META_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static int getMouseWheelZoomModifierMask() {
  		if(isMac()){
  			return InputEvent.META_DOWN_MASK;
  		}else{
  			return InputEvent.CTRL_DOWN_MASK;
  		}
  	}
  	/*
  	public static KeyStroke getDecreaseFontSizeKeyAccelerator() {
  		return KeyStroke.getKeyStroke('-');
  	}
  
  	public static KeyStroke getIncreaseFontSizeKeyAccelerator() {
  		return KeyStroke.getKeyStroke('+');
  	}
  	 */
  
  	public static KeyStroke getPasteKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getIncreaseFontSizeKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke('+');//, InputEvent.META_DOWN_MASK); // Command and + is not working on mac
  		}else{
  			return KeyStroke.getKeyStroke('+');//, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getDecreaseFontSizeKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke('-');//, InputEvent.META_DOWN_MASK); // Command and - is not working on mac
  		}else{
  			return KeyStroke.getKeyStroke('-');//, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getClearKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);
  		}
  	}
  
  	public static KeyStroke getDeleteKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getUndoKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_Z, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getRedoKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_Y, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getMoveSelectionUpKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getMoveSelectionDownKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getMoveSelectedRightKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getMoveSelectedLeftKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  
  	public static KeyStroke getInsertGapMoveRightKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0);
  		}
  	}
  
  	public static KeyStroke getInsertGapMoveLeftKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getDeleteGapMoveLeftKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,0);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE,0);
  		}
  	}
  
  	public static KeyStroke getDeleteGapMoveRightKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_BACK_SPACE, InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getToggleTranslationKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getToggleIgnoreGapInTranslationKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.META_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getSelectAllKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getSelectionExpandRightKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getSelectionExpandLeftKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  	
  	public static KeyStroke getSelectionExpandTopKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  	
  	public static KeyStroke getSelectionExpandDownKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.ALT_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  
  	public static KeyStroke getToggleTranslationOnePosKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.META_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.CTRL_DOWN_MASK | InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getToggleTranslateShowBothKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.ALT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getToggleTranslateShowAACodeKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_T, InputEvent.SHIFT_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getGoToPosKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke incReadingFrameKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getExpandSelectionDownKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke decReadingFrameKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.SHIFT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, InputEvent.SHIFT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke countStopCodonsKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.META_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK | InputEvent.ALT_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getAddOrRemoveExcludesKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getSaveFileAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getOpenFileAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  
  	public static KeyStroke getNewFileAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getPrintAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_P, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static String getStandardCommandModifierKeyName() {
  		if(isMac()){
  			return "⌘";
  		}else{
  			return "Ctrl";
  		}
  	}
  
  	public static KeyStroke getRenameKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0);
  		}
  	}
  
  	public static KeyStroke getCloseWinKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_W, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  	public static KeyStroke getFocusNextWinKeyAccelerator() {
  		if(isMac()){
  			return KeyStroke.getKeyStroke(KeyEvent.VK_D, InputEvent.META_DOWN_MASK);
  		}else{
  			return KeyStroke.getKeyStroke(KeyEvent.VK_H, InputEvent.CTRL_DOWN_MASK);
  		}
  	}
  
  
  	/**
  	 * Swing menus are looking pretty bad on Linux when the GTK LaF is used (See
  	 * bug #6925412). It will most likely never be fixed anytime soon so this
  	 * method provides a workaround for it. It uses reflection to change the GTK
  	 * style objects of Swing so popup menu borders have a minimum thickness of
  	 * 1 and menu separators have a minimum vertical thickness of 1.
  	 */
  
  	public static final void installGtkPopupBugWorkaround()
  	{
  		// Get current look-and-feel implementation class
  		LookAndFeel laf = UIManager.getLookAndFeel();
  		Class<?> lafClass = laf.getClass();
  
  		// Do nothing when not using the problematic LaF
  		if (!lafClass.getName().equals(
  				"com.sun.java.swing.plaf.gtk.GTKLookAndFeel")) return;
  
  		// We do reflection from here on. Failure is silently ignored. The
  		// workaround is simply not installed when something goes wrong here
  		try
  		{
  			// Access the GTK style factory
  			Field field = lafClass.getDeclaredField("styleFactory");
  			boolean accessible = field.isAccessible();
  			field.setAccessible(true);
  			Object styleFactory = field.get(laf);
  			field.setAccessible(accessible);
  
  			// Fix the horizontal and vertical thickness of popup menu style
  			Object style = getGtkStyle(styleFactory, new JPopupMenu(),
  					"POPUP_MENU");
  			fixGtkThickness(style, "yThickness");
  			fixGtkThickness(style, "xThickness");
  
  			// Fix the vertical thickness of the popup menu separator style
  			style = getGtkStyle(styleFactory, new JSeparator(), 
  					"POPUP_MENU_SEPARATOR");
  			fixGtkThickness(style, "yThickness");
  		}
  		catch (Exception e)
  		{
  			// Silently ignored. Workaround can't be applied.
  		}
  	}
  
  	/**
  	 * Called internally by installGtkPopupBugWorkaround to fix the thickness
  	 * of a GTK style field by setting it to a minimum value of 1.
  	 * 
  	 * @param style
  	 *            The GTK style object.
  	 * @param fieldName
  	 *            The field name.
  	 * @throws Exception
  	 *             When reflection fails.
  	 */
  	private static void fixGtkThickness(Object style, String fieldName)
  			throws Exception
  	{
  		Field field = style.getClass().getDeclaredField(fieldName);
  		boolean accessible = field.isAccessible();
  		field.setAccessible(true);
  		field.setInt(style, Math.max(1, field.getInt(style)));
  		field.setAccessible(accessible);
  	}
  
  	/**
  	 * Called internally by installGtkPopupBugWorkaround. Returns a specific
  	 * GTK style object.
  	 * 
  	 * @param styleFactory
  	 *            The GTK style factory.
  	 * @param component
  	 *            The target component of the style.
  	 * @param regionName
  	 *            The name of the target region of the style.
  	 * @return The GTK style.
  	 * @throws Exception
  	 *             When reflection fails.
  	 */
  	private static Object getGtkStyle(Object styleFactory,
  			JComponent component, String regionName) throws Exception
  	{
  		// Create the region object
  		Class<?> regionClass = Class.forName("javax.swing.plaf.synth.Region");
  		Field field = regionClass.getField(regionName);
  		Object region = field.get(regionClass);
  
  		// Get and return the style
  		Class<?> styleFactoryClass = styleFactory.getClass();
  		Method method = styleFactoryClass.getMethod("getStyle",
  				new Class<?>[] { JComponent.class, regionClass });
  		boolean accessible = method.isAccessible();
  		method.setAccessible(true);
  		Object style = method.invoke(styleFactory, component, region);
  		method.setAccessible(accessible);
  		return style;
  	}
  
  	/*
  	 * 
  	 * Register through reflection and other OS wont be affected
  	 * 
  	 */
  	public static boolean registerMacAdapter(AliView aliView) {
  		boolean registerOK = false;
  
  		if(isMac()){
  			logger.info("register Mac Adapter");			
  			if(isJavaVersion8orLower()){
  				logger.info("Doing pre-java-9 version of Mac application adapter via com.apple.eawt");
  				Application macApplication = new DefaultApplication();
  				macApplication.addApplicationListener(aliView);
  				macApplication.addPreferencesMenuItem();
  				macApplication.setEnabledPreferencesMenu(true);
  				registerOK = true;
  			}else {
  				logger.info("Doing java-9 version of Mac application adapter via javax.awt.desktop");
  				OSXHandlerJava9 adapter = new OSXHandlerJava9();
  				registerOK = true;
  			}
  		}
  		return registerOK;
  	}
  
  	public static String getMonospacedFontName() {
  		if(isMac()){
  			return "Courier";
  		}else{
  			return Font.MONOSPACED;
  		}
  	}
  
  }
  