diff --git a/plugins/org.eclipse.actf.visualization.gui/src/org/eclipse/actf/visualization/gui/ui/actions/WindowListAction.java b/plugins/org.eclipse.actf.visualization.gui/src/org/eclipse/actf/visualization/gui/ui/actions/WindowListAction.java
index acb2aa2..417ea57 100644
--- a/plugins/org.eclipse.actf.visualization.gui/src/org/eclipse/actf/visualization/gui/ui/actions/WindowListAction.java
+++ b/plugins/org.eclipse.actf.visualization.gui/src/org/eclipse/actf/visualization/gui/ui/actions/WindowListAction.java
@@ -32,7 +32,6 @@
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
 import org.eclipse.swt.events.SelectionListener;
-import org.eclipse.swt.internal.win32.OS;
 import org.eclipse.swt.widgets.Control;
 import org.eclipse.swt.widgets.Menu;
 import org.eclipse.swt.widgets.MenuItem;
@@ -40,164 +39,185 @@
 import org.eclipse.ui.IWorkbenchWindowPulldownDelegate2;
 import org.eclipse.ui.PlatformUI;
 
-
 public class WindowListAction implements IWorkbenchWindowPulldownDelegate2 {
 
 	private boolean switchPerspective = true;
-    
-    private IWorkbenchWindow window;
-	
-    public void run(IAction action) {}
 
-    public void selectionChanged(IAction action, ISelection selection) {}
+	private IWorkbenchWindow window;
 
-    public void dispose() {}
+	public void run(IAction action) {
+	}
 
-    public void init(IWorkbenchWindow window) {
-        this.window = window;
-    }
-    
-    public Menu getMenu(Control parent) {
-        return null;
-    }
-    
-    public Menu getMenu(Menu parent) {
-        Menu menu = new Menu(parent);
-        menu.addMenuListener(menuListener);
-        return menu;
-    }
-    
-    private MenuListener menuListener = new MenuAdapter() {
-        public void menuShown(MenuEvent e) {
-            Menu menu = (Menu)e.getSource();
-            MenuItem[] items = menu.getItems();
-            for( int i=0; i<items.length; i++ ) {
-                items[i].dispose();
-            }
-            String defaultID = TargetWindow.getID();
-            boolean hasEmbedBrowser = false;
-            TargetWindowDataCollector collector = new TargetWindowDataCollector();
-            String[] categories = collector.getCategories(new CategoryComparator());
-            for( int c=0; c<categories.length; c++ ) {
-                String category = categories[c];
-                Menu submenu = menu;
-                if( null != category ) {
-                    MenuItem item = new MenuItem(menu,SWT.CASCADE);
-                    item.setText(category);
-                    submenu = new Menu(item);
-                    item.setMenu(submenu);
-                }
-                Object[] elements = collector.getElements(category);
-                for( int i=0; i<elements.length; i++ ) {
-                    Object element = elements[i];
-                    String title = TargetWindow.getTitle(element);
-                    if( null != title ) {
-                        hasEmbedBrowser |= TargetWindow.isEmbeddedBrowser(element);
-                        MenuItem item = new MenuItem(submenu,SWT.RADIO);
-                        item.setText(title);
-                        item.setData(element);
-                        if( TargetWindow.getID(element).equals(defaultID) ) {
-                            item.setSelection(true);
-                        }
-                        item.addArmListener(armListener);
-                        item.addSelectionListener(selectionListener);
-                    }
-                }
-            }
-            if( categories.length > 0 ) {
-                new MenuItem(menu,SWT.SEPARATOR);
-            }
-            final MenuItem bringTopItem = new MenuItem(menu,SWT.CHECK);
-            bringTopItem.setText(Messages.getString("msaa.bringToTop")); //$NON-NLS-1$
-            bringTopItem.setSelection(GuiPreferenceManager.getPreferenceBoolean(GuiPreferenceConstants.AlwaysOnTop));
-            if( TargetWindow.isEmbeddedBrowser() ) {
-                bringTopItem.setEnabled(false);
-            }
-            bringTopItem.addSelectionListener(new SelectionAdapter(){
-				public void widgetSelected(SelectionEvent e) {
-					GuiPreferenceManager.setPreference(GuiPreferenceConstants.AlwaysOnTop,bringTopItem.getSelection());
+	public void selectionChanged(IAction action, ISelection selection) {
+	}
+
+	public void dispose() {
+	}
+
+	public void init(IWorkbenchWindow window) {
+		this.window = window;
+	}
+
+	public Menu getMenu(Control parent) {
+		return null;
+	}
+
+	public Menu getMenu(Menu parent) {
+		Menu menu = new Menu(parent);
+		menu.addMenuListener(menuListener);
+		return menu;
+	}
+
+	private MenuListener menuListener = new MenuAdapter() {
+		public void menuShown(MenuEvent e) {
+			Menu menu = (Menu) e.getSource();
+			MenuItem[] items = menu.getItems();
+			for (int i = 0; i < items.length; i++) {
+				items[i].dispose();
+			}
+			String defaultID = TargetWindow.getID();
+			boolean hasEmbedBrowser = false;
+			TargetWindowDataCollector collector = new TargetWindowDataCollector();
+			String[] categories = collector
+					.getCategories(new CategoryComparator());
+			for (int c = 0; c < categories.length; c++) {
+				String category = categories[c];
+				Menu submenu = menu;
+				if (null != category) {
+					MenuItem item = new MenuItem(menu, SWT.CASCADE);
+					item.setText(category);
+					submenu = new Menu(item);
+					item.setMenu(submenu);
 				}
-            });
-            if( hasEmbedBrowser ) {
-                final MenuItem switchItem = new MenuItem(menu,SWT.CHECK);
-                switchItem.setText(Messages.getString("msaa.switchPerspective")); //$NON-NLS-1$
-                switchItem.setSelection(switchPerspective);
-                switchItem.addSelectionListener(new SelectionAdapter(){
-    				public void widgetSelected(SelectionEvent e) {
-    					switchPerspective = switchItem.getSelection();
-    					if( !switchPerspective ) {
-                            showInternalViewer(true);
-    					}
-    				}
-                });
-            }
-        }
-    };
-    
-    private ArmListener armListener = new ArmListener() {
-        public void widgetArmed(ArmEvent e) {
-            Object element = ((MenuItem)e.getSource()).getData();
-            if( null != element ) {
-                int hwnd = TargetWindow.getRootWindow(element);
-                HighlightComposite.flashRectangle(WindowUtil.GetWindowRectangle(hwnd));
-            }
-        }
-    };
-    
-    private SelectionListener selectionListener = new SelectionAdapter() {
-        public void widgetSelected(SelectionEvent event) {
-            TargetWindow.setCurrentElement(((MenuItem)event.getSource()).getData());
-            int hwnd = TargetWindow.getWindowHandle();
-            boolean isEmbedded = TargetWindow.isEmbeddedBrowser();
-            try {
-        		if( setWindowOrder(GuiPreferenceManager.getPreferenceBoolean(GuiPreferenceConstants.AlwaysOnTop)) ) {
-                    WindowUtil.BringWindowToTop(hwnd);
-                    WindowUtil.BringWindowToTop(hwnd);
-        		}
-            	if( switchPerspective ) {
-                    showInternalViewer(isEmbedded);
-            	}
-            }
-            catch( Exception e) {
-                e.printStackTrace();
-            }
-            MSAAViewRegistory.refreshRootObject();
-        }
-    };
-    
-    private void showInternalViewer(boolean bShow) {
-        try {
-            window.getActivePage().setEditorAreaVisible(bShow);
-        }
-        catch( Exception e ) {
-        }
-    }
-    
-    public static boolean setWindowOrder(boolean topMost) {
-    	if( topMost && TargetWindow.isEmbeddedBrowser() ) {
-    		topMost = false;
-    	}
-        IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
-        OS.SetWindowPos( window.getShell().handle,
-                         topMost ? OS.HWND_TOPMOST : OS.HWND_NOTOPMOST,
-                         0, 0, 0, 0, OS.SWP_NOSIZE | OS.SWP_NOMOVE );
-        return topMost;
-    }
-    
-    private static final String CATEGORY_BROWSER = Messages.getString("msaa.external_browsers"); //$NON-NLS-1$
-    private static final String CATEGORY_WINDOW = Messages.getString("msaa.external_windows"); //$NON-NLS-1$
-    private class CategoryComparator implements Comparator {
-        private Collator collator = Collator.getInstance();
-        public int compare(Object o1, Object o2) {
-            int w = getWeight(o1);
-            int rc = w-getWeight(o2);
-            return (0==rc && 0==w) ? collator.compare(o1,o2) : rc;
-        }
-        public int getWeight(Object o) {
-            if( null == o )                     {return -1;}
-            if( CATEGORY_BROWSER.equals(o) )    {return 1;}
-            if( CATEGORY_WINDOW.equals(o) )     {return 2;}
-            return 0;
-        }
-    }
+				Object[] elements = collector.getElements(category);
+				for (int i = 0; i < elements.length; i++) {
+					Object element = elements[i];
+					String title = TargetWindow.getTitle(element);
+					if (null != title) {
+						hasEmbedBrowser |= TargetWindow
+								.isEmbeddedBrowser(element);
+						MenuItem item = new MenuItem(submenu, SWT.RADIO);
+						item.setText(title);
+						item.setData(element);
+						if (TargetWindow.getID(element).equals(defaultID)) {
+							item.setSelection(true);
+						}
+						item.addArmListener(armListener);
+						item.addSelectionListener(selectionListener);
+					}
+				}
+			}
+			if (categories.length > 0) {
+				new MenuItem(menu, SWT.SEPARATOR);
+			}
+			final MenuItem bringTopItem = new MenuItem(menu, SWT.CHECK);
+			bringTopItem.setText(Messages.getString("msaa.bringToTop")); //$NON-NLS-1$
+			bringTopItem.setSelection(GuiPreferenceManager
+					.getPreferenceBoolean(GuiPreferenceConstants.AlwaysOnTop));
+			if (TargetWindow.isEmbeddedBrowser()) {
+				bringTopItem.setEnabled(false);
+			}
+			bringTopItem.addSelectionListener(new SelectionAdapter() {
+				public void widgetSelected(SelectionEvent e) {
+					GuiPreferenceManager.setPreference(
+							GuiPreferenceConstants.AlwaysOnTop, bringTopItem
+									.getSelection());
+				}
+			});
+			if (hasEmbedBrowser) {
+				final MenuItem switchItem = new MenuItem(menu, SWT.CHECK);
+				switchItem
+						.setText(Messages.getString("msaa.switchPerspective")); //$NON-NLS-1$
+				switchItem.setSelection(switchPerspective);
+				switchItem.addSelectionListener(new SelectionAdapter() {
+					public void widgetSelected(SelectionEvent e) {
+						switchPerspective = switchItem.getSelection();
+						if (!switchPerspective) {
+							showInternalViewer(true);
+						}
+					}
+				});
+			}
+		}
+	};
+
+	private ArmListener armListener = new ArmListener() {
+		public void widgetArmed(ArmEvent e) {
+			Object element = ((MenuItem) e.getSource()).getData();
+			if (null != element) {
+				int hwnd = TargetWindow.getRootWindow(element);
+				HighlightComposite.flashRectangle(WindowUtil
+						.GetWindowRectangle(hwnd));
+			}
+		}
+	};
+
+	private SelectionListener selectionListener = new SelectionAdapter() {
+		public void widgetSelected(SelectionEvent event) {
+			TargetWindow.setCurrentElement(((MenuItem) event.getSource())
+					.getData());
+			int hwnd = TargetWindow.getWindowHandle();
+			boolean isEmbedded = TargetWindow.isEmbeddedBrowser();
+			try {
+				if (setWindowOrder(GuiPreferenceManager
+						.getPreferenceBoolean(GuiPreferenceConstants.AlwaysOnTop))) {
+					WindowUtil.BringWindowToTop(hwnd);
+					WindowUtil.BringWindowToTop(hwnd);
+				}
+				if (switchPerspective) {
+					showInternalViewer(isEmbedded);
+				}
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
+			MSAAViewRegistory.refreshRootObject();
+		}
+	};
+
+	private void showInternalViewer(boolean bShow) {
+		try {
+			window.getActivePage().setEditorAreaVisible(bShow);
+		} catch (Exception e) {
+		}
+	}
+
+	public static boolean setWindowOrder(boolean topMost) {
+		if (topMost && TargetWindow.isEmbeddedBrowser()) {
+			topMost = false;
+		}
+		IWorkbenchWindow window = PlatformUI.getWorkbench()
+				.getActiveWorkbenchWindow();
+		WindowUtil.SetWindowPos(window.getShell().handle,
+				topMost ? WindowUtil.HWND_TOPMOST : WindowUtil.HWND_NOTOPMOST,
+				0, 0, 0, 0, WindowUtil.SWP_NOSIZE | WindowUtil.SWP_NOMOVE);
+		return topMost;
+	}
+
+	private static final String CATEGORY_BROWSER = Messages
+			.getString("msaa.external_browsers"); //$NON-NLS-1$
+	private static final String CATEGORY_WINDOW = Messages
+			.getString("msaa.external_windows"); //$NON-NLS-1$
+
+	private class CategoryComparator implements Comparator {
+		private Collator collator = Collator.getInstance();
+
+		public int compare(Object o1, Object o2) {
+			int w = getWeight(o1);
+			int rc = w - getWeight(o2);
+			return (0 == rc && 0 == w) ? collator.compare(o1, o2) : rc;
+		}
+
+		public int getWeight(Object o) {
+			if (null == o) {
+				return -1;
+			}
+			if (CATEGORY_BROWSER.equals(o)) {
+				return 1;
+			}
+			if (CATEGORY_WINDOW.equals(o)) {
+				return 2;
+			}
+			return 0;
+		}
+	}
 }
