14830 smf: panel doesn't react well to failed server connection
authorStephen Talley <stephen.talley@oracle.com>
Wed, 21 Jul 2010 20:26:39 -0400
changeset 545 7a29a25b92e2
parent 544 c16652047d4f
child 546 b284ba298d57
14830 smf: panel doesn't react well to failed server connection 14831 firewall: firewall panel doesn't react well to failed server connection 16616 connection tracking code is widespread, verbose, and often redundant 16617 PropertyChangeForwarder should use a single path to instantiation 16618 MBeanServerConnection listeners should supply server-side filter 16619 RemoteFileSystemView and friends should be part of panel API 16620 HasTimeZoneMXBean implies TimeZoneMXBean class exists 16621 comment typo in PropertyChangeListeners.java
usr/src/apis/file.xml
usr/src/java/util/org/opensolaris/os/vp/util/misc/event/EventListeners.java
usr/src/java/util/org/opensolaris/os/vp/util/misc/event/PropertyChangeListeners.java
usr/src/java/vpanels/common/org/opensolaris/os/vp/common/remotefile/FileBrowserUtil.java
usr/src/java/vpanels/common/org/opensolaris/os/vp/common/remotefile/RemoteFile.java
usr/src/java/vpanels/common/org/opensolaris/os/vp/common/remotefile/RemoteFileSystemView.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/ConnectionTracker.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/MXBeanTracker.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/PropertyChangeForwarder.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/remotefile/FileBrowserUtil.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/remotefile/RemoteFile.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/remotefile/RemoteFileSystemView.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/AbstractServicePanelDescriptor.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/AggregatedRefreshService.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/HasService.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/HasServiceTracker.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/InstanceManagedObject.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/RepoManagedObject.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/ScfUtil.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/ServiceManagedObject.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/ServiceTracker.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleHasService.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfPropertyGroupInfo.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfPropertyInfo.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfServiceInfo.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfEnabledProperty.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfManagedObject.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfPropertyGroupInfo.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfServiceInfo.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfUtil.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/time/HasTimeMXBean.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ClearServiceAction.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/EnableServiceAction.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceSettingsPanel.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceStatusControl.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceStatusPanel.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceSwingPanelDescriptor.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/timezone/HasTimeZoneMXBean.java
usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/timezone/TimeZoneModel.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ApacheInfo.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ApachePanelDescriptor.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MainControl.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeType.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/Module.java
usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHost.java
usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmPanelDescriptor.java
usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmSettingsTab.java
usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CustomCoreSchemeEditControl.java
usr/src/java/vpanels/panels/examples/org/opensolaris/os/vp/panels/example/time2/client/swing/TimePanelDescriptor.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/EnableServiceAction.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallPanelDescriptor.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/GlobalControl.java
usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/ServiceEditControl.java
usr/src/java/vpanels/panels/hypervisor/org/opensolaris/os/vp/panels/hypervisor/client/swing/HypervisorPanelDescriptor.java
usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/common/SharemgrEventMonitor.java
usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/common/SharemgrPanelDescriptor.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/GeneralControl.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/HasSmfManagedObject.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/InstanceTabbedControl.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/MainControl.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/ServiceTabbedControl.java
usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/SmfPanelDescriptor.java
usr/src/java/vpanels/panels/svcs/org/opensolaris/os/vp/panels/svcs/client/swing/SvcsPanelDescriptor.java
usr/src/java/vpanels/panels/sysid/org/opensolaris/os/vp/panels/sysid/client/swing/SysIdPanelDescriptor.java
usr/src/java/vpanels/panels/sysid/org/opensolaris/os/vp/panels/sysid/client/swing/TimeZoneControl.java
usr/src/java/vpanels/panels/sysmon/org/opensolaris/os/vp/panels/sysmon/client/swing/SmfMonitoredResource.java
usr/src/java/vpanels/panels/sysmon/org/opensolaris/os/vp/panels/sysmon/client/swing/SysMonPanelDescriptor.java
usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/MainControl.java
usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/NTPModel.java
usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimeModel.java
usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimePanelDescriptor.java
usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimeZoneObject.java
usr/src/java/vpanels/panels/usermgr/org/opensolaris/os/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java
--- a/usr/src/apis/file.xml	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/apis/file.xml	Wed Jul 21 20:26:39 2010 -0400
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <!--
- Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- Use is subject to license terms.
+ Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
 
  CDDL HEADER START
 
@@ -26,7 +25,7 @@
 <interface xmlns="http://www.opensolaris.org/ns/adr" name="files">
 
 	<pragma domain="java" name="package"
-	    value="org.opensolaris.os.vp.common.remotefile" />
+	    value="org.opensolaris.os.vp.panel.common.remotefile" />
 
 	<type name="FileSnapshot">
 		<field type="string" name="path" />
--- a/usr/src/java/util/org/opensolaris/os/vp/util/misc/event/EventListeners.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/misc/event/EventListeners.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.util.misc.event;
@@ -145,6 +144,14 @@
     }
 
     /**
+     * Removes all managed listeners.
+     */
+    public synchronized void clear() {
+	first = null;
+	modCount = 0;
+    }
+
+    /**
      * Notifies each listener of the given event, in the order in which they
      * were {@link #add add}ed.
      *
--- a/usr/src/java/util/org/opensolaris/os/vp/util/misc/event/PropertyChangeListeners.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/util/org/opensolaris/os/vp/util/misc/event/PropertyChangeListeners.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.util.misc.event;
@@ -38,7 +37,7 @@
     // Instance data
     //
 
-    // Map of PropertyChangeListeners intested only in a single property
+    // Map of PropertyChangeListeners interested only in a single property
     private Map<PropertyChangeListener, List<String>> map =
 	new HashMap<PropertyChangeListener, List<String>>();
 
--- a/usr/src/java/vpanels/common/org/opensolaris/os/vp/common/remotefile/FileBrowserUtil.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.common.remotefile;
-
-import javax.management.*;
-import org.opensolaris.os.vp.common.panel.MBeanUtil;
-
-public class FileBrowserUtil {
-    //
-    // Static data
-    //
-
-    private static final String DOMAIN = MBeanUtil.VP_DOMAIN + ".filebrowser";
-    public static final ObjectName OBJECT_NAME =
-	MBeanUtil.makeObjectName(DOMAIN, "Files");
-}
--- a/usr/src/java/vpanels/common/org/opensolaris/os/vp/common/remotefile/RemoteFile.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,310 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.common.remotefile;
-
-import java.io.*;
-import java.util.List;
-import org.opensolaris.os.rad.ObjectException;
-
-@SuppressWarnings({"serial"})
-public class RemoteFile extends File {
-    //
-    // Instance data
-    //
-
-    private FileBrowserMXBean browser;
-    private FileSnapshot snapshot;
-
-    //
-    // Constructors
-    //
-
-    public RemoteFile(FileBrowserMXBean browser, FileSnapshot snapshot) {
-	super(snapshot.getPath());
-	this.browser = browser;
-	this.snapshot = snapshot;
-    }
-
-    //
-    // File methods
-    //
-
-    @Override
-    public boolean canExecute() {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean canRead() {
-	return snapshot.isReadable();
-    }
-
-    @Override
-    public boolean canWrite() {
-	return snapshot.isWritable();
-    }
-
-    @Override
-    public boolean createNewFile() throws IOException {
-	throw new IOException("operation not supported");
-    }
-
-    @Override
-    public boolean delete() {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public void deleteOnExit() {
-	// Operation not supported
-    }
-
-    @Override
-    public boolean exists() {
-	return snapshot.isExists();
-    }
-
-    @Override
-    public RemoteFile getAbsoluteFile() {
-	// RemoteFiles are based on FileSnapshots which are always absolute
-	return this;
-    }
-
-    @Override
-    public String getAbsolutePath() {
-	return snapshot.getAbsolutePath();
-    }
-
-    @Override
-    public RemoteFile getCanonicalFile() throws IOException {
-	if (snapshot.isCanonical()) {
-	    return this;
-	}
-	String path = snapshot.getCanonicalPath();
-	try {
-	    return new RemoteFile(browser, browser.getFile(path));
-	} catch (ObjectException e) {
-	    throw new IOException(e);
-	}
-    }
-
-    @Override
-    public String getCanonicalPath() throws IOException {
-	String path = snapshot.getCanonicalPath();
-	if (path == null) {
-	    // FileSnapshot could not canonicalize path
-	    throw new IOException(
-		"unable to canonicalize path: " + getAbsolutePath());
-	}
-
-	return path;
-    }
-
-    @Override
-    public long getFreeSpace() {
-	return snapshot.getFreeSpace();
-    }
-
-    @Override
-    public RemoteFile getParentFile() {
-	String parent = getParent();
-	try {
-	    return parent == null ? null :
-		new RemoteFile(browser, browser.getFile(parent));
-	} catch (ObjectException e) {
-	    /* Not correct, but our choices are limited */
-	    return null;
-	}
-    }
-
-    @Override
-    public long getTotalSpace() {
-	return snapshot.getTotalSpace();
-    }
-
-    @Override
-    public long getUsableSpace() {
-	return snapshot.getUsableSpace();
-    }
-
-    @Override
-    public boolean isAbsolute() {
-	return snapshot.isAbsolute();
-    }
-
-    @Override
-    public boolean isDirectory() {
-	return snapshot.isDirectory();
-    }
-
-    @Override
-    public boolean isFile() {
-	return snapshot.isFile();
-    }
-
-    @Override
-    public boolean isHidden() {
-	return snapshot.isHidden();
-    }
-
-    @Override
-    public long lastModified() {
-	return snapshot.getLastModified().getTime();
-    }
-
-    @Override
-    public long length() {
-	return snapshot.getLength();
-    }
-
-    @Override
-    public String[] list() {
-	try {
-	    List<FileSnapshot> snapshots = browser.getFiles(getAbsolutePath());
-	    String[] names = new String[snapshots.size()];
-
-	    int i = 0;
-	    for (FileSnapshot ss : snapshots)
-		names[i++] = ss.getBaseName();
-
-	    return names;
-	} catch (ObjectException e) {
-	    return null;
-	}
-    }
-
-    @Override
-    public RemoteFile[] listFiles() {
-	try {
-	    List<FileSnapshot> snapshots = browser.getFiles(getAbsolutePath());
-	    return toFiles(snapshots);
-	} catch (ObjectException e) {
-	    return null;
-	}
-    }
-
-    @Override
-    public boolean mkdir() {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean mkdirs() {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean renameTo(File dest) {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setExecutable(boolean executable) {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setExecutable(boolean executable, boolean ownerOnly) {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setLastModified(long time) {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setReadable(boolean readable) {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setReadable(boolean readable, boolean ownerOnly) {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setReadOnly() {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setWritable(boolean writable) {
-	// Operation not supported
-	return false;
-    }
-
-    @Override
-    public boolean setWritable(boolean writable, boolean ownerOnly) {
-	// Operation not supported
-	return false;
-    }
-
-    //
-    // RemoteFile methods
-    //
-
-    public FileBrowserMXBean getBrowser() {
-	return browser;
-    }
-
-    public FileSnapshot getSnapshot() {
-	return snapshot;
-    }
-
-    protected RemoteFile[] toFiles(List<FileSnapshot> snapshots) {
-	return toFiles(browser, snapshots);
-    }
-
-    //
-    // Static methods
-    //
-
-    public static RemoteFile[] toFiles(
-	FileBrowserMXBean browser, List<FileSnapshot> snapshots) {
-
-	RemoteFile[] files = new RemoteFile[snapshots.size()];
-
-	int i = 0;
-	for (FileSnapshot ss : snapshots)
-	    files[i++] = new RemoteFile(browser, ss);
-
-	return files;
-    }
-
-}
--- a/usr/src/java/vpanels/common/org/opensolaris/os/vp/common/remotefile/RemoteFileSystemView.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.common.remotefile;
-
-import java.io.*;
-import java.util.*;
-import javax.management.*;
-import javax.swing.*;
-import javax.swing.filechooser.FileSystemView;
-import org.opensolaris.os.rad.ObjectException;
-import org.opensolaris.os.vp.util.misc.IOUtil;
-
-public class RemoteFileSystemView extends FileSystemView {
-    //
-    // Instance data
-    //
-
-    private FileBrowserMXBean browser;
-
-    //
-    // Constructors
-    //
-
-    public RemoteFileSystemView(MBeanServerConnection mbsc) {
-	ObjectName oName = FileBrowserUtil.OBJECT_NAME;
-	browser = JMX.newMXBeanProxy(mbsc, oName, FileBrowserMXBean.class);
-    }
-
-    //
-    // FileSystemView methods
-    //
-
-    @Override
-    public RemoteFile createFileObject(File dir, String fileName) {
-	if (dir != null) {
-	    fileName = dir.getAbsolutePath() + File.separator + fileName;
-	}
-	return createFileObject(fileName);
-    }
-
-    @Override
-    public RemoteFile createFileObject(String path) {
-	try {
-	    FileSnapshot snap = browser.getFile(path);
-	    return snap != null ?
-		new RemoteFile(browser, browser.getFile(path)) : null;
-	} catch (ObjectException ex) {
-	    return null;
-	}
-    }
-
-    @Override
-    protected RemoteFile createFileSystemRoot(File file) {
-	return toRemoteFile(file);
-    }
-
-    @Override
-    public RemoteFile createNewFolder(File containingDir) throws IOException {
-	throw new IOException("operation not supported");
-    }
-
-    @Override
-    public RemoteFile getChild(File parent, String fileName) {
-	return createFileObject(parent, fileName);
-    }
-
-    @Override
-    public RemoteFile getDefaultDirectory() {
-	RemoteFile home = getHomeDirectory();
-	if (home.exists()) {
-	    return home;
-	}
-
-	return getRoots()[0];
-    }
-
-    @Override
-    public RemoteFile[] getFiles(File dir, boolean useFileHiding) {
-	List<RemoteFile> files = new ArrayList<RemoteFile>();
-
-	List<FileSnapshot> snapshots;
-	try {
-		snapshots = browser.getFiles(dir.getAbsolutePath());
-	} catch (ObjectException e) {
-		return (new RemoteFile[0]);
-	} catch (java.lang.reflect.UndeclaredThrowableException e) {
-		/*
-		 * Our caller, BasicDirectoryModel, may interrupt us at
-		 * any time.  This can cause exceptions to be thrown.
-		 * In our case, our transport may throw an exception
-		 * which is mapped by the MBean proxy to a
-		 * UndeclaredThrowableException.
-		 *
-		 * Unfortunately, the FileSystemView interface doesn't
-		 * allow us to throw exceptions, and letting an
-		 * unchecked exception by results in noise to the
-		 * user's terminal.  BasicDirectoryModel does check to
-		 * see if the thread has been interrupted, though, so
-		 * we mark ourselves as such and return an empty list
-		 * of files.
-		 */
-		Thread.currentThread().interrupt();
-		return (new RemoteFile[0]);
-	}
-	for (FileSnapshot ss : snapshots) {
-	    if (!useFileHiding || !ss.isHidden()) {
-		files.add(new RemoteFile(browser, ss));
-	    }
-	}
-
-	return files.toArray(new RemoteFile[files.size()]);
-    }
-
-    @Override
-    public RemoteFile getHomeDirectory() {
-	return createFileObject(System.getProperty("user.home"));
-    }
-
-    @Override
-    public RemoteFile getParentDirectory(File dir) {
-	return toRemoteFile(dir).getParentFile();
-    }
-
-    @Override
-    public RemoteFile[] getRoots() {
-	List<FileSnapshot> snapshots = browser.getRoots();
-	return RemoteFile.toFiles(browser, snapshots);
-    }
-
-    @Override
-    public String getSystemDisplayName(File file) {
-	return file.getName();
-    }
-
-    @Override
-    public Icon getSystemIcon(File file) {
-	return UIManager.getIcon(file.isDirectory() ?
-	    "FileView.directoryIcon" : "FileView.fileIcon");
-    }
-
-    @Override
-    public String getSystemTypeDescription(File file) {
-	return null;
-    }
-
-    @Override
-    public boolean isComputerNode(File dir) {
-	return false;
-    }
-
-    @Override
-    public boolean isDrive(File dir) {
-	return isFileSystemRoot(dir);
-    }
-
-    @Override
-    public boolean isFileSystem(File file) {
-	return true;
-    }
-
-    @Override
-    public boolean isFileSystemRoot(File dir) {
-	String fullName = IOUtil.getFullName(dir);
-
-	RemoteFile[] roots = getRoots();
-	for (RemoteFile root : roots) {
-	    if (fullName.equals(IOUtil.getFullName(root))) {
-		return true;
-	    }
-	}
-
-	return false;
-    }
-
-    @Override
-    public boolean isFloppyDrive(File dir) {
-	return false;
-    }
-
-    @Override
-    public boolean isHiddenFile(File file) {
-	return toRemoteFile(file).isHidden();
-    }
-
-    @Override
-    public boolean isParent(File dir, File file) {
-	boolean retVal = dir.equals(file.getParentFile());
-	return retVal;
-    }
-
-    @Override
-    public boolean isRoot(File file) {
-	return isFileSystemRoot(file);
-    }
-
-    @Override
-    public Boolean isTraversable(File file) {
-	return file.isDirectory();
-    }
-
-    //
-    // Private methods
-    //
-
-    private RemoteFile toRemoteFile(File file) {
-	if (file instanceof RemoteFile) {
-	    RemoteFile rFile = (RemoteFile)file;
-	    if (rFile.getBrowser() == browser) {
-		return rFile;
-	    }
-	}
-	return createFileObject(file.getAbsolutePath());
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/ConnectionTracker.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,494 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common;
+
+import java.beans.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.logging.*;
+import javax.management.*;
+import org.opensolaris.os.vp.util.misc.ObjectUtil;
+import org.opensolaris.os.vp.util.misc.event.PropertyChangeListeners;
+
+/**
+ * The {@code ConnectionTracker} class manages listeners that depend on
+ * connections.
+ * </p>
+ * {@code ConnectionListener}s that depend on a {@link ClientContext} are
+ * automatically removed/added when the tracked {@code ClientContext}
+ * fails/changes.
+ * </p>
+ * {@code NotificationListener}s that depend on an {@code MBeanServerConnection}
+ * are automatically removed/added when the tracked {@code
+ * MBeanServerConnection} or {@code ObjectName} changes.
+ * </p>
+ * Property change notifications are sent out when the tracked {@code
+ * ClientContext}, {@code ConnectionInfo}, {@code MBeanServerConnection}, or
+ * {@code ObjectName} changes.
+ */
+public class ConnectionTracker implements ConnectionListener {
+    //
+    // Inner classes
+    //
+
+    private abstract class NotifyParams<O> {
+	private O listener;
+	private NotificationFilter filter;
+	private Object handback;
+
+	//
+	// Constructors
+	//
+
+        public NotifyParams(O listener, NotificationFilter filter,
+	    Object handback) {
+
+	    this.listener = listener;
+	    this.filter = filter;
+	    this.handback = handback;
+	}
+
+	//
+	// NotifyParams methods
+	//
+
+	public boolean equals(Object listener) {
+	    return ObjectUtil.equals(this.listener, listener);
+	}
+
+        public boolean equals(Object listener, NotificationFilter filter,
+	    Object handback) {
+
+	    return ObjectUtil.equals(this.listener, listener) &&
+		ObjectUtil.equals(this.filter, filter) &&
+		ObjectUtil.equals(this.handback, handback);
+	}
+
+	public O getListener() {
+	    return listener;
+	}
+
+	public NotificationFilter getFilter() {
+	    return filter;
+	}
+
+	public Object getHandback() {
+	    return handback;
+	}
+
+        public abstract void add()
+	    throws InstanceNotFoundException, IOException;
+
+        public abstract void remove()
+	    throws InstanceNotFoundException, IOException;
+    }
+
+    private class ListenerNotifyParams
+	extends NotifyParams<NotificationListener> {
+	//
+	// Constructors
+	//
+
+        public ListenerNotifyParams(NotificationListener listener,
+	    NotificationFilter filter, Object handback) {
+	    super(listener, filter, handback);
+	}
+
+	//
+	// ListenerNotifyParams methods
+	//
+
+	@Override
+	public void add() throws InstanceNotFoundException, IOException {
+	    if (mbsc != null && oName != null) {
+                mbsc.addNotificationListener(oName, getListener(), getFilter(),
+		    getHandback());
+	    }
+	}
+
+	@Override
+        public void remove() throws InstanceNotFoundException,
+	    IOException {
+
+	    if (mbsc != null && oName != null) {
+		try {
+		    mbsc.removeNotificationListener(oName, getListener(),
+			getFilter(), getHandback());
+		} catch (ListenerNotFoundException ignore) {
+		}
+	    }
+	}
+    }
+
+    private class ObjectNameNotifyParams extends NotifyParams<ObjectName> {
+	//
+	// Constructors
+	//
+
+        public ObjectNameNotifyParams(ObjectName listener,
+	    NotificationFilter filter, Object handback) {
+	    super(listener, filter, handback);
+	}
+
+	//
+	// ObjectNameNotifyParams methods
+	//
+
+	@Override
+	public void add() throws InstanceNotFoundException, IOException {
+	    if (mbsc != null && oName != null) {
+                mbsc.addNotificationListener(oName, getListener(), getFilter(),
+		    getHandback());
+	    }
+	}
+
+	@Override
+        public void remove() throws InstanceNotFoundException,
+	    IOException {
+
+	    if (mbsc != null && oName != null) {
+		try {
+		    mbsc.removeNotificationListener(oName, getListener(),
+			getFilter(), getHandback());
+		} catch (ListenerNotFoundException ignore) {
+		}
+	    }
+	}
+    }
+
+    //
+    // Static data
+    //
+
+    /**
+     * The name of the property that changes with {@link #setClientContext}.
+     */
+    public static final String PROPERTY_CONTEXT = "context";
+
+    /**
+     * The name of the property that changes with {@link #setConnectionInfo}.
+     */
+    public static final String PROPERTY_INFO = "info";
+
+    /**
+     * The name of the property that changes with {@link
+     * #setMBeanServerConnection}.
+     */
+    public static final String PROPERTY_MBSC = "mbsc";
+
+    /**
+     * The name of the property that changes with {@link #setObjectName}.
+     */
+    public static final String PROPERTY_OBJECTNAME = "objectname";
+
+    //
+    // Instance data
+    //
+
+    private ClientContext context;
+    private ConnectionInfo info;
+    private MBeanServerConnection mbsc;
+    private ObjectName oName;
+    private PropertyChangeListeners pListeners = new PropertyChangeListeners();
+    private List<NotifyParams> nListeners = new LinkedList<NotifyParams>();
+
+    //
+    // Constructors
+    //
+
+    public ConnectionTracker() {
+    }
+
+    public ConnectionTracker(ClientContext context, ObjectName oName) {
+	this();
+	try {
+	    setClientContext(context);
+	    setObjectName(oName);
+
+	// Impossible because no NotificationListeners have been added yet
+	} catch (InstanceNotFoundException impossible) {
+	} catch (IOException impossible) {
+	}
+    }
+
+    //
+    // ConnectionListener methods
+    //
+
+    @Override
+    public void connectionChanged(ConnectionEvent event) {
+	Exception e = null;
+	ConnectionInfo info = event.getConnectionInfo();
+
+	try {
+	    setConnectionInfo(info);
+	} catch (InstanceNotFoundException ex) {
+	    e = ex;
+	} catch (IOException ex) {
+	    e = ex;
+	}
+
+	if (e != null) {
+	    Logger.getLogger(getClass().getName()).log(
+		Level.SEVERE, "could not communicate with remote host", e);
+	}
+    }
+
+    @Override
+    public void connectionFailed(ConnectionEvent event) {
+	try {
+	    setConnectionInfo(null);
+	} catch (Throwable ignore) {
+	}
+    }
+
+    //
+    // ConnectionTracker methods
+    //
+
+    public void addNotificationListener(NotificationListener listener,
+        NotificationFilter filter, Object handback)
+	throws InstanceNotFoundException, IOException {
+
+        NotifyParams params = new ListenerNotifyParams(listener, filter,
+	    handback);
+
+	params.add();
+	nListeners.add(params);
+    }
+
+    public void addNotificationListener(ObjectName listener,
+	NotificationFilter filter, Object handback)
+	throws InstanceNotFoundException, IOException {
+
+        NotifyParams params = new ObjectNameNotifyParams(listener, filter,
+	    handback);
+
+	params.add();
+	nListeners.add(params);
+    }
+
+    public void addPropertyChangeListener(String propName,
+	PropertyChangeListener listener) {
+	pListeners.add(propName, listener);
+    }
+
+    public void addPropertyChangeListener(PropertyChangeListener listener) {
+	pListeners.add(listener);
+    }
+
+    /**
+     * Sets the {@link #getClientContext ClientContext} to {@code null} and
+     * removes all listeners, ignoring any exceptions along the way.
+     */
+    public void dispose() {
+	try {
+	    setClientContext(null);
+
+        // If something prevented us from removing a notification listener, it
+        // probably doesn't matter anymore.
+	} catch (InstanceNotFoundException ignore) {
+	} catch (IOException ignore) {
+	}
+
+	pListeners.clear();
+	nListeners.clear();
+    }
+
+    public ClientContext getClientContext() {
+	return context;
+    }
+
+    public ConnectionInfo getConnectionInfo() {
+	return info;
+    }
+
+    public MBeanServerConnection getMBeanServerConnection() {
+	return mbsc;
+    }
+
+    public ObjectName getObjectName() {
+	return oName;
+    }
+
+    protected PropertyChangeListeners getPropertyChangeListeners() {
+	return pListeners;
+    }
+
+    public void removeNotificationListener(NotificationListener listener)
+	throws InstanceNotFoundException, IOException {
+
+	for (Iterator<NotifyParams> i = nListeners.iterator(); i.hasNext();) {
+	    NotifyParams params = i.next();
+	    if (params.equals(listener)) {
+		params.remove();
+		i.remove();
+	    }
+	}
+    }
+
+    public void removeNotificationListener(NotificationListener listener,
+	NotificationFilter filter, Object handback)
+	throws InstanceNotFoundException, IOException {
+
+	for (Iterator<NotifyParams> i = nListeners.iterator(); i.hasNext();) {
+	    NotifyParams params = i.next();
+	    if (params.equals(listener, filter, handback)) {
+		params.remove();
+		i.remove();
+		return;
+	    }
+	}
+    }
+
+    public void removeNotificationListener(ObjectName listener)
+	throws InstanceNotFoundException, IOException {
+	for (Iterator<NotifyParams> i = nListeners.iterator(); i.hasNext();) {
+	    NotifyParams params = i.next();
+	    if (params.equals(listener)) {
+		params.remove();
+		i.remove();
+	    }
+	}
+    }
+
+    public void removeNotificationListener(ObjectName name, ObjectName listener,
+	NotificationFilter filter, Object handback)
+	throws InstanceNotFoundException, IOException {
+
+	for (Iterator<NotifyParams> i = nListeners.iterator(); i.hasNext();) {
+	    NotifyParams params = i.next();
+	    if (params.equals(listener, filter, handback)) {
+		params.remove();
+		i.remove();
+		return;
+	    }
+	}
+    }
+
+    public void removePropertyChangeListener(String propName,
+	PropertyChangeListener listener) {
+	pListeners.remove(propName, listener);
+    }
+
+    public void removePropertyChangeListener(PropertyChangeListener listener) {
+	pListeners.remove(listener);
+    }
+
+    public void setClientContext(ClientContext context)
+	throws InstanceNotFoundException, IOException {
+
+	if (this.context != context) {
+	    if (this.context != null) {
+		this.context.removeConnectionListener(this);
+	    }
+
+	    PropertyChangeEvent e = new PropertyChangeEvent(
+		this, PROPERTY_CONTEXT, this.context, context);
+	    this.context = context;
+	    pListeners.propertyChange(e);
+
+            setConnectionInfo(context == null ? null :
+		context.getConnectionInfo());
+
+	    if (context != null) {
+		context.addConnectionListener(this);
+	    }
+	}
+    }
+
+    protected void setConnectionInfo(ConnectionInfo info)
+	throws InstanceNotFoundException, IOException {
+
+	if (this.info != info) {
+	    PropertyChangeEvent e = new PropertyChangeEvent(
+		this, PROPERTY_INFO, this.info, info);
+	    this.info = info;
+	    pListeners.propertyChange(e);
+
+	    setMBeanServerConnection(info == null ? null :
+		info.getConnector().getMBeanServerConnection());
+	}
+    }
+
+    protected void setMBeanServerConnection(MBeanServerConnection mbsc)
+	throws InstanceNotFoundException, IOException {
+
+	if (this.mbsc != mbsc) {
+	    removeNotificationListeners();
+
+	    PropertyChangeEvent e = new PropertyChangeEvent(
+		this, PROPERTY_MBSC, this.mbsc, mbsc);
+	    this.mbsc = mbsc;
+	    pListeners.propertyChange(e);
+
+	    addNotificationListeners();
+	}
+    }
+
+    public void setObjectName(ObjectName oName)
+	throws InstanceNotFoundException, IOException {
+
+	if (!ObjectUtil.equals(this.oName, oName)) {
+	    removeNotificationListeners();
+
+	    PropertyChangeEvent e = new PropertyChangeEvent(
+		this, PROPERTY_OBJECTNAME, this.oName, oName);
+	    this.oName = oName;
+	    pListeners.propertyChange(e);
+
+	    addNotificationListeners();
+	}
+    }
+
+    //
+    // Private methods
+    //
+
+    private void addNotificationListeners()
+	throws InstanceNotFoundException, IOException {
+
+	if (mbsc != null && oName != null) {
+	    for (NotifyParams params : nListeners) {
+		params.add();
+	    }
+	}
+    }
+
+    private void removeNotificationListeners() {
+	if (mbsc != null && oName != null) {
+	    for (NotifyParams params : nListeners) {
+		try {
+		    params.remove();
+
+		// If something prevented us from removing a notification
+		// listener, it probably doesn't matter anymore.
+		} catch (Throwable ignore) {
+		}
+	    }
+	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/MXBeanTracker.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,121 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common;
+
+import java.beans.*;
+import javax.management.*;
+import org.opensolaris.os.vp.util.misc.event.PropertyChangeListeners;
+
+/**
+ * The {@code MXBeanTracker} is a {@link ConnectionTracker} that automatically
+ * creates and re-creates an {@link #getBean MXBean} after changes in the {@link
+ * #setMBeanServerConnection MBeanServerConnection} or {@link #setObjectName
+ * ObjectName}.
+ * </p>
+ * A property change notification is sent out when the tracked {@code MXBean}
+ * changes.
+ */
+public class MXBeanTracker<T> extends ConnectionTracker {
+    //
+    // Static data
+    //
+
+    /**
+     * The name of the property that changes with {@link #setBean}.
+     */
+    public static final String PROPERTY_BEAN = "bean";
+
+    //
+    // Instance data
+    //
+
+    private Class<T> clazz;
+    private T bean;
+
+    private PropertyChangeListener pListener =
+	new PropertyChangeListener() {
+	    @Override
+	    public void propertyChange(PropertyChangeEvent event) {
+		setBean();
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public MXBeanTracker(Class<T> clazz) {
+	init(clazz);
+    }
+
+    public MXBeanTracker(Class<T> clazz, ClientContext context,
+	ObjectName oName) {
+	super(context, oName);
+	init(clazz);
+    }
+
+    //
+    // MXBeanTracker methods
+    //
+
+    public T getBean() {
+	return bean;
+    }
+
+    protected void setBean(T bean) {
+	if (this.bean != bean) {
+	    PropertyChangeEvent e = new PropertyChangeEvent(
+		this, PROPERTY_BEAN, this.bean, bean);
+	    this.bean = bean;
+	    getPropertyChangeListeners().propertyChange(e);
+	}
+    }
+
+    //
+    // Private methods
+    //
+
+    private void init(Class<T> clazz) {
+	this.clazz = clazz;
+	addPropertyChangeListener(PROPERTY_MBSC, pListener);
+	addPropertyChangeListener(PROPERTY_OBJECTNAME, pListener);
+	setBean();
+    }
+
+    private void setBean() {
+	T bean = null;
+
+	MBeanServerConnection mbsc = getMBeanServerConnection();
+	if (mbsc != null) {
+	    ObjectName oName = getObjectName();
+	    if (oName != null) {
+		bean = JMX.newMXBeanProxy(mbsc, oName, clazz);
+	    }
+	}
+
+	setBean(bean);
+    }
+}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/PropertyChangeForwarder.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/model/PropertyChangeForwarder.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,15 +20,13 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 
 package org.opensolaris.os.vp.panel.common.model;
 
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
+import java.beans.*;
 
 /**
  * A {@code PropertyChangeListener} that forwards {@code PropertyChangeEvent}s
@@ -48,7 +46,7 @@
      * made the source of the event
      */
     public PropertyChangeForwarder(AbstractManagedObject mo) {
-	source_ = managedObject_ = mo;
+	this(mo, mo);
     }
 
     /**
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/remotefile/FileBrowserUtil.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.remotefile;
+
+import javax.management.ObjectName;
+import org.opensolaris.os.vp.common.panel.MBeanUtil;
+
+public class FileBrowserUtil {
+    //
+    // Static data
+    //
+
+    private static final String DOMAIN = MBeanUtil.VP_DOMAIN + ".filebrowser";
+    public static final ObjectName OBJECT_NAME =
+	MBeanUtil.makeObjectName(DOMAIN, "Files");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/remotefile/RemoteFile.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,309 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.remotefile;
+
+import java.io.*;
+import java.util.List;
+import org.opensolaris.os.rad.ObjectException;
+
+@SuppressWarnings({"serial"})
+public class RemoteFile extends File {
+    //
+    // Instance data
+    //
+
+    private FileBrowserMXBean browser;
+    private FileSnapshot snapshot;
+
+    //
+    // Constructors
+    //
+
+    public RemoteFile(FileBrowserMXBean browser, FileSnapshot snapshot) {
+	super(snapshot.getPath());
+	this.browser = browser;
+	this.snapshot = snapshot;
+    }
+
+    //
+    // File methods
+    //
+
+    @Override
+    public boolean canExecute() {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean canRead() {
+	return snapshot.isReadable();
+    }
+
+    @Override
+    public boolean canWrite() {
+	return snapshot.isWritable();
+    }
+
+    @Override
+    public boolean createNewFile() throws IOException {
+	throw new IOException("operation not supported");
+    }
+
+    @Override
+    public boolean delete() {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public void deleteOnExit() {
+	// Operation not supported
+    }
+
+    @Override
+    public boolean exists() {
+	return snapshot.isExists();
+    }
+
+    @Override
+    public RemoteFile getAbsoluteFile() {
+	// RemoteFiles are based on FileSnapshots which are always absolute
+	return this;
+    }
+
+    @Override
+    public String getAbsolutePath() {
+	return snapshot.getAbsolutePath();
+    }
+
+    @Override
+    public RemoteFile getCanonicalFile() throws IOException {
+	if (snapshot.isCanonical()) {
+	    return this;
+	}
+	String path = snapshot.getCanonicalPath();
+	try {
+	    return new RemoteFile(browser, browser.getFile(path));
+	} catch (ObjectException e) {
+	    throw new IOException(e);
+	}
+    }
+
+    @Override
+    public String getCanonicalPath() throws IOException {
+	String path = snapshot.getCanonicalPath();
+	if (path == null) {
+	    // FileSnapshot could not canonicalize path
+	    throw new IOException(
+		"unable to canonicalize path: " + getAbsolutePath());
+	}
+
+	return path;
+    }
+
+    @Override
+    public long getFreeSpace() {
+	return snapshot.getFreeSpace();
+    }
+
+    @Override
+    public RemoteFile getParentFile() {
+	String parent = getParent();
+	try {
+	    return parent == null ? null :
+		new RemoteFile(browser, browser.getFile(parent));
+	} catch (ObjectException e) {
+	    /* Not correct, but our choices are limited */
+	    return null;
+	}
+    }
+
+    @Override
+    public long getTotalSpace() {
+	return snapshot.getTotalSpace();
+    }
+
+    @Override
+    public long getUsableSpace() {
+	return snapshot.getUsableSpace();
+    }
+
+    @Override
+    public boolean isAbsolute() {
+	return snapshot.isAbsolute();
+    }
+
+    @Override
+    public boolean isDirectory() {
+	return snapshot.isDirectory();
+    }
+
+    @Override
+    public boolean isFile() {
+	return snapshot.isFile();
+    }
+
+    @Override
+    public boolean isHidden() {
+	return snapshot.isHidden();
+    }
+
+    @Override
+    public long lastModified() {
+	return snapshot.getLastModified().getTime();
+    }
+
+    @Override
+    public long length() {
+	return snapshot.getLength();
+    }
+
+    @Override
+    public String[] list() {
+	try {
+	    List<FileSnapshot> snapshots = browser.getFiles(getAbsolutePath());
+	    String[] names = new String[snapshots.size()];
+
+	    int i = 0;
+	    for (FileSnapshot ss : snapshots)
+		names[i++] = ss.getBaseName();
+
+	    return names;
+	} catch (ObjectException e) {
+	    return null;
+	}
+    }
+
+    @Override
+    public RemoteFile[] listFiles() {
+	try {
+	    List<FileSnapshot> snapshots = browser.getFiles(getAbsolutePath());
+	    return toFiles(snapshots);
+	} catch (ObjectException e) {
+	    return null;
+	}
+    }
+
+    @Override
+    public boolean mkdir() {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean mkdirs() {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean renameTo(File dest) {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setExecutable(boolean executable) {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setExecutable(boolean executable, boolean ownerOnly) {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setLastModified(long time) {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setReadable(boolean readable) {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setReadable(boolean readable, boolean ownerOnly) {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setReadOnly() {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setWritable(boolean writable) {
+	// Operation not supported
+	return false;
+    }
+
+    @Override
+    public boolean setWritable(boolean writable, boolean ownerOnly) {
+	// Operation not supported
+	return false;
+    }
+
+    //
+    // RemoteFile methods
+    //
+
+    public FileBrowserMXBean getBrowser() {
+	return browser;
+    }
+
+    public FileSnapshot getSnapshot() {
+	return snapshot;
+    }
+
+    protected RemoteFile[] toFiles(List<FileSnapshot> snapshots) {
+	return toFiles(browser, snapshots);
+    }
+
+    //
+    // Static methods
+    //
+
+    public static RemoteFile[] toFiles(
+	FileBrowserMXBean browser, List<FileSnapshot> snapshots) {
+
+	RemoteFile[] files = new RemoteFile[snapshots.size()];
+
+	int i = 0;
+	for (FileSnapshot ss : snapshots)
+	    files[i++] = new RemoteFile(browser, ss);
+
+	return files;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/remotefile/RemoteFileSystemView.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,252 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.remotefile;
+
+import java.io.*;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.util.*;
+import javax.swing.*;
+import javax.swing.filechooser.FileSystemView;
+import org.opensolaris.os.rad.ObjectException;
+import org.opensolaris.os.vp.panel.common.*;
+import org.opensolaris.os.vp.util.misc.IOUtil;
+
+public class RemoteFileSystemView extends FileSystemView {
+    //
+    // Instance data
+    //
+
+    private MXBeanTracker<FileBrowserMXBean> tracker;
+
+    //
+    // Constructors
+    //
+
+    public RemoteFileSystemView(ClientContext context) {
+	tracker = new MXBeanTracker<FileBrowserMXBean>(
+	    FileBrowserMXBean.class, context, FileBrowserUtil.OBJECT_NAME);
+    }
+
+    //
+    // FileSystemView methods
+    //
+
+    @Override
+    public RemoteFile createFileObject(File dir, String fileName) {
+	if (dir != null) {
+	    fileName = dir.getAbsolutePath() + File.separator + fileName;
+	}
+	return createFileObject(fileName);
+    }
+
+    @Override
+    public RemoteFile createFileObject(String path) {
+	try {
+	    FileBrowserMXBean browser = tracker.getBean();
+	    FileSnapshot snap = browser.getFile(path);
+	    return snap != null ?
+		new RemoteFile(browser, browser.getFile(path)) : null;
+	} catch (ObjectException ex) {
+	    return null;
+	}
+    }
+
+    @Override
+    protected RemoteFile createFileSystemRoot(File file) {
+	return toRemoteFile(file);
+    }
+
+    @Override
+    public RemoteFile createNewFolder(File containingDir) throws IOException {
+	throw new IOException("operation not supported");
+    }
+
+    @Override
+    public RemoteFile getChild(File parent, String fileName) {
+	return createFileObject(parent, fileName);
+    }
+
+    @Override
+    public RemoteFile getDefaultDirectory() {
+	RemoteFile home = getHomeDirectory();
+	if (home.exists()) {
+	    return home;
+	}
+
+	return getRoots()[0];
+    }
+
+    @Override
+    public RemoteFile[] getFiles(File dir, boolean useFileHiding) {
+	List<RemoteFile> files = new ArrayList<RemoteFile>();
+
+	FileBrowserMXBean browser = tracker.getBean();
+	List<FileSnapshot> snapshots;
+	try {
+		snapshots = browser.getFiles(dir.getAbsolutePath());
+	} catch (ObjectException e) {
+		return (new RemoteFile[0]);
+	} catch (java.lang.reflect.UndeclaredThrowableException e) {
+		/*
+		 * Our caller, BasicDirectoryModel, may interrupt us at
+		 * any time.  This can cause exceptions to be thrown.
+		 * In our case, our transport may throw an exception
+		 * which is mapped by the MBean proxy to a
+		 * UndeclaredThrowableException.
+		 *
+		 * Unfortunately, the FileSystemView interface doesn't
+		 * allow us to throw exceptions, and letting an
+		 * unchecked exception by results in noise to the
+		 * user's terminal.  BasicDirectoryModel does check to
+		 * see if the thread has been interrupted, though, so
+		 * we mark ourselves as such and return an empty list
+		 * of files.
+		 */
+		Thread.currentThread().interrupt();
+		return (new RemoteFile[0]);
+	}
+	for (FileSnapshot ss : snapshots) {
+	    if (!useFileHiding || !ss.isHidden()) {
+		files.add(new RemoteFile(browser, ss));
+	    }
+	}
+
+	return files.toArray(new RemoteFile[files.size()]);
+    }
+
+    @Override
+    public RemoteFile getHomeDirectory() {
+	return createFileObject(System.getProperty("user.home"));
+    }
+
+    @Override
+    public RemoteFile getParentDirectory(File dir) {
+	return toRemoteFile(dir).getParentFile();
+    }
+
+    @Override
+    public RemoteFile[] getRoots() {
+	FileBrowserMXBean browser = tracker.getBean();
+	List<FileSnapshot> snapshots = browser.getRoots();
+	return RemoteFile.toFiles(browser, snapshots);
+    }
+
+    @Override
+    public String getSystemDisplayName(File file) {
+	return file.getName();
+    }
+
+    @Override
+    public Icon getSystemIcon(File file) {
+	return UIManager.getIcon(file.isDirectory() ?
+	    "FileView.directoryIcon" : "FileView.fileIcon");
+    }
+
+    @Override
+    public String getSystemTypeDescription(File file) {
+	return null;
+    }
+
+    @Override
+    public boolean isComputerNode(File dir) {
+	return false;
+    }
+
+    @Override
+    public boolean isDrive(File dir) {
+	return isFileSystemRoot(dir);
+    }
+
+    @Override
+    public boolean isFileSystem(File file) {
+	return true;
+    }
+
+    @Override
+    public boolean isFileSystemRoot(File dir) {
+	String fullName = IOUtil.getFullName(dir);
+
+	RemoteFile[] roots = getRoots();
+	for (RemoteFile root : roots) {
+	    if (fullName.equals(IOUtil.getFullName(root))) {
+		return true;
+	    }
+	}
+
+	return false;
+    }
+
+    @Override
+    public boolean isFloppyDrive(File dir) {
+	return false;
+    }
+
+    @Override
+    public boolean isHiddenFile(File file) {
+	return toRemoteFile(file).isHidden();
+    }
+
+    @Override
+    public boolean isParent(File dir, File file) {
+	boolean retVal = dir.equals(file.getParentFile());
+	return retVal;
+    }
+
+    @Override
+    public boolean isRoot(File file) {
+	return isFileSystemRoot(file);
+    }
+
+    @Override
+    public Boolean isTraversable(File file) {
+	return file.isDirectory();
+    }
+
+    //
+    // RemoteFileSystemView methods
+    //
+
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    public void dispose() {
+	tracker.dispose();
+    }
+
+    //
+    // Private methods
+    //
+
+    private RemoteFile toRemoteFile(File file) {
+	if (file instanceof RemoteFile) {
+	    RemoteFile rFile = (RemoteFile)file;
+	    if (rFile.getBrowser() == tracker.getBean()) {
+		return rFile;
+	    }
+	}
+	return createFileObject(file.getAbsolutePath());
+    }
+}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/AbstractServicePanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/AbstractServicePanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -25,12 +25,11 @@
 
 package org.opensolaris.os.vp.panel.common.smf;
 
-import java.beans.PropertyChangeEvent;
+import java.beans.*;
 import java.io.IOException;
 import java.util.Locale;
 import java.util.logging.Level;
 import javax.management.*;
-import javax.management.remote.JMXConnector;
 import org.opensolaris.os.rad.jmx.RadNotification;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.smf.*;
@@ -40,32 +39,60 @@
 
 @SuppressWarnings({"serial"})
 public abstract class AbstractServicePanelDescriptor<C extends ManagedObject>
-    extends AbstractPanelDescriptor<C>
-    implements ConnectionListener, NotificationListener, SmfServiceInfo,
+    extends AbstractPanelDescriptor<C> implements HasService, HasServiceTracker,
     Enableable {
 
     //
     // Static data
     //
 
-    public static final String PROPERTY_SERVICE = "service";
     public static final String PROPERTY_STATE = "state";
 
     //
     // Instance data
     //
 
-    private MBeanServerConnection mbsc;
-    private ObjectName oName;
+    private ServiceTracker tracker;
     private String serviceName;
     private String instanceName;
 
-    private AggregatedRefreshService service =
-	new AggregatedRefreshService();
-
     private SmfEnabledProperty enabledProperty =
 	new SmfEnabledProperty(PROPERTY_ENABLED, this);
 
+    private PropertyChangeListener serviceListener =
+	new PropertyChangeListener() {
+	    @Override
+	    public void propertyChange(PropertyChangeEvent event) {
+		serviceChanged();
+            }
+	};
+
+    /**
+     * Handles changes to this {@code AbstractServicePanelDescriptor}'s service.
+     * This implementation listens only for {@code StateChangeNotification}s and
+     * fires a {@code PropertyChangeEvent} to registered {@code
+     * PropertyChangeEvent}s.  Subclasses with {@code ManagedObject} children
+     * may wish to override/extend this implementation.
+     */
+    private NotificationListener notifyListener =
+	new NotificationListener() {
+	    @Override
+	    public void handleNotification(Notification n, Object h) {
+		StateChange sc = ((RadNotification)n).getPayload(
+		    StateChange.class);
+
+		firePropertyChange(PROPERTY_STATE, null, sc.getState());
+		setStatus();
+		setStatusText();
+		try {
+		    refresh(false);
+		} catch (Exception e) {
+		    getLog().log(Level.SEVERE, Finder.getString(
+			"error.repository.read"), e);
+		}
+	    }
+	};
+
     //
     // Constructors
     //
@@ -79,14 +106,14 @@
 	this.serviceName = serviceName;
 	this.instanceName = instanceName;
 
-	oName = ServiceUtil.toObjectName(serviceName, instanceName);
+	tracker = new ServiceTracker(context, serviceName, instanceName);
+        tracker.addNotificationListener(notifyListener,
+	    SmfUtil.NOTIFY_FILTER_STATE_CHANGE, null);
+        tracker.addPropertyChangeListener(ServiceTracker.PROPERTY_SERVICE,
+	    serviceListener);
 
-	connectionChanged(context.getConnectionInfo());
-	context.addConnectionListener(this);
-
+	serviceChanged();
 	setName();
-	setStatus();
-	setStatusText();
     }
 
     //
@@ -94,6 +121,15 @@
     //
 
     /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	tracker.dispose();
+	super.dispose();
+    }
+
+    /**
      * Default implementation that returns {@code null}.
      */
     @Override
@@ -101,7 +137,7 @@
 	String locale = Locale.getDefault().getLanguage();
 
 	try {
-	    return service.getDescription(locale);
+	    return getService().getDescription(locale);
 	} catch (ScfException e) {
 	    getLog().log(Level.SEVERE, Finder.getString("error.scf.general"),
 		 e);
@@ -114,25 +150,6 @@
     // PanelDescriptor methods
     //
 
-    /**
-     * Removes this {@code AbstractServicePanelDescriptor} as a
-     * {@code NotificationListener} for changes to its service.
-     */
-    @Override
-    public void dispose() {
-	super.dispose();
-
-	ClientContext context = getClientContext();
-	context.removeConnectionListener(this);
-
-	try {
-	    mbsc.removeNotificationListener(oName, this);
-	} catch (Throwable e) {
-	    getLog().log(Level.SEVERE, Finder.getString("error.scf.general"),
-		 e);
-	}
-    }
-
     @Override
     public boolean getHasFullPrivileges() {
 	ConnectionInfo info = getClientContext().getConnectionInfo();
@@ -146,79 +163,23 @@
     }
 
     //
-    // ConnectionListener methods
-    //
-
-    @Override
-    public void connectionChanged(ConnectionEvent event) {
-	Exception e = null;
-	ConnectionInfo info = event.getConnectionInfo();
-
-	try {
-	    connectionChanged(info);
-	} catch (InstanceNotFoundException ex) {
-	    e = ex;
-	} catch (IOException ex) {
-	    e = ex;
-	}
-
-	if (e != null) {
-	    getLog().log(Level.SEVERE, Finder.getString("error.jmx.general"),
-		 e);
-	}
-    }
-
-    @Override
-    public void connectionFailed(ConnectionEvent event) {
-	if (mbsc != null) {
-	    try {
-		mbsc.removeNotificationListener(oName, this);
-
-	    // The connection is likely already closed
-	    } catch (Throwable ignore) {
-	    }
-
-	    mbsc = null;
-	}
-    }
-
-    //
-    // NotificationListener methods
-    //
-
-    /**
-     * Handles changes to this {@code AbstractServicePanelDescriptor}'s service.
-     * This implementation listens only for {@code StateChangeNotification}s and
-     * fires a {@code PropertyChangeEvent} to registered {@code
-     * PropertyChangeEvent}s.  Subclasses with {@code ManagedObject} children
-     * may wish to override/extend this implementation.
-     */
-    @Override
-    public void handleNotification(Notification n, Object h) {
-	StateChange sc;
-	if (!(n instanceof RadNotification) ||
-	    !n.getType().equals("statechange") ||
-	    (sc = ((RadNotification)n).getPayload(StateChange.class)) == null)
-	    return;
-
-	firePropertyChange(PROPERTY_STATE, null, sc.getState());
-	setStatus();
-	setStatusText();
-	try {
-	    refresh(false);
-	} catch (Exception e) {
-	    getLog().log(Level.SEVERE, Finder.getString(
-		"error.repository.read"), e);
-	}
-    }
-
-    //
-    // SmfServiceInfo methods
+    // HasService methods
     //
 
     @Override
     public AggregatedRefreshService getService() {
-	return service;
+	// This may be called indirectly by the superclass before tracker has
+	// been instantiated
+	return tracker == null ? null : tracker.getService();
+    }
+
+    //
+    // HasServiceTracker methods
+    //
+
+    @Override
+    public ServiceTracker getServiceTracker() {
+	return tracker;
     }
 
     //
@@ -242,6 +203,7 @@
     protected ManagedObjectStatus getCalculatedStatus() {
 	ManagedObjectStatus status = super.getCalculatedStatus();
 
+	ServiceMXBean service = getService();
 	if (service != null) {
 	    ManagedObjectStatus sStatus = null;
 
@@ -264,6 +226,7 @@
     protected String getCalculatedStatusText() {
 	SmfState state = null;
 	SmfState nextState = null;
+	ServiceMXBean service = getService();
 
 	try {
 	    state = service.getState();
@@ -281,45 +244,6 @@
     // AbstractServicePanelDescriptor methods
     //
 
-    /**
-     * Called by {@link #connectionChanged(ConnectionEvent)}, adds this
-     * {@code AbstractServicePanelDescriptor} as a listener to the contained
-     * {@code MBeanServerConnection}.
-     * <p>
-     * Subclasses that override this method should be sure to call into this
-     * superclass implementation.
-     *
-     * @param	    info
-     *		    the new {@link ConnectionInfo}
-     *
-     * @exception   InstanceNotFoundException
-     *		    thrown by {@code
-     *		    MBeanServerConnection.{add,remove}NotificationListener}
-     *
-     * @exception   IOException
-     *		    thrown by {@code JMXConnector.getMBeanServerConnection}
-     */
-    protected void connectionChanged(ConnectionInfo info)
-	throws InstanceNotFoundException, IOException {
-
-	if (mbsc != null) {
-	    try {
-		mbsc.removeNotificationListener(oName, this);
-
-	    // If something prevented us from removing ourselves as a
-	    // notification listener, it probably doesn't matter anymore.
-	    } catch (Throwable ignore) {
-	    }
-	    mbsc = null;
-	}
-
-	mbsc = info.getConnector().getMBeanServerConnection();
-	mbsc.addNotificationListener(oName, this, null, null);
-
-	setService(new ServiceMXBeanAdaptor(JMX.newMXBeanProxy(mbsc, oName,
-	    ServiceInfoMXBean.class)));
-    }
-
     public SmfEnabledProperty getEnabledProperty() {
 	return enabledProperty;
     }
@@ -328,14 +252,6 @@
 	return instanceName;
     }
 
-    public MBeanServerConnection getMBeanServerConnection() {
-	return mbsc;
-    }
-
-    public ObjectName getObjectName() {
-	return oName;
-    }
-
     public String getServiceName() {
 	return serviceName;
     }
@@ -372,7 +288,7 @@
 	String locale = Locale.getDefault().getLanguage();
 
 	try {
-	    name = service.getCommonName(locale);
+	    name = getService().getCommonName(locale);
 	} catch (ScfException e) {
 	    getLog().log(Level.SEVERE, Finder.getString("error.scf.general"),
 		 e);
@@ -385,24 +301,12 @@
 	setName(name);
     }
 
-    /**
-     * Called by {@link #connectionChanged(ConnectionInfo)}, sets the given
-     * {@link ServiceMXBean} in this {@code AbstractServicePanelDescriptor}.
-     * <p>
-     * Subclasses that override this method should be sure to call into this
-     * superclass implementation.
-     *
-     * @param	    service
-     *		    the new {@link ServiceMXBean}
-     */
-    protected void setService(ServiceMXBean service) {
-	ServiceMXBean old = this.service.getService();
+    //
+    // Private methods
+    //
 
-	if (service != old) {
-	    PropertyChangeEvent e = new PropertyChangeEvent(this,
-		PROPERTY_SERVICE, old, service);
-	    this.service.setService(service);
-	    firePropertyChange(e);
-	}
+    private void serviceChanged() {
+	setStatus();
+	setStatusText();
     }
 }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/AggregatedRefreshService.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/AggregatedRefreshService.java	Wed Jul 21 20:26:39 2010 -0400
@@ -305,20 +305,42 @@
 	this.refreshNeeded = refreshNeeded;
     }
 
-    public synchronized void setService(ServiceMXBean service) {
+    /**
+     * Sets the underlying {@link ServiceMXBean} for this {@code
+     * AggregatedRefreshService}.
+     *
+     * @param	    force
+     *		    {@code true} to ignore and reset the {@link #pause paused}
+     *		    and {@link #getRefreshNeeded refresh needed} states of this
+     *		    {@code AggregatedRefreshService}
+     *
+     * @exception   IllegalStateException
+     *		    if this {@code AggregatedRefreshService} is {@link #pause
+     *		    paused} or {@link #getRefreshNeeded needs a refresh}
+     */
+    public synchronized void setService(ServiceMXBean service, boolean force) {
 	if (this.service != service) {
-	    if (paused) {
+	    if (paused && !force) {
 		throw new IllegalStateException(
 		    "must not change service when paused");
 	    }
 
-	    if (refreshNeeded) {
+	    if (refreshNeeded && !force) {
 		throw new IllegalStateException(
 		    "must not change service with pending refresh");
 	    }
 
+	    paused = false;
+	    refreshNeeded = false;
 	    this.service = service;
 	    this.instance = null;
 	}
     }
+
+    /**
+     * Calls {@link #setService setService}{@code (service, true)}.
+     */
+    public void setService(ServiceMXBean service) {
+	setService(service, true);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/HasService.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,33 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.smf;
+
+public interface HasService {
+    /**
+     * Gets the service.
+     */
+    ServiceMXBean getService();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/HasServiceTracker.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.smf;
+
+public interface HasServiceTracker {
+    ServiceTracker getServiceTracker();
+}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/InstanceManagedObject.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/InstanceManagedObject.java	Wed Jul 21 20:26:39 2010 -0400
@@ -27,62 +27,56 @@
 
 import java.beans.PropertyChangeEvent;
 import java.util.Date;
-import javax.management.MBeanServerConnection;
 import org.opensolaris.os.scf.common.*;
 import org.opensolaris.os.smf.*;
+import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.model.ManagedObjectStatus;
 import org.opensolaris.os.vp.util.misc.*;
 
 public class InstanceManagedObject extends SmfManagedObject
-    implements Enableable
-{
+    implements Enableable {
     /* public static final String PROPERTY_ENABLED = "enabled"; */
     public static final String PROPERTY_STATE = "state";
 
-    private SmfState state_;
-    private Date stime_;
-    private final FMRI svcFmri_;
+    private SmfState state;
+    private Date stime;
+    private final FMRI svcFmri;
 
-    InstanceManagedObject(MBeanServerConnection mbsc, Instance inst)
-    {
-	super(mbsc, inst.getFmri(), inst.getObjectName());
+    InstanceManagedObject(ClientContext context, Instance inst) {
+	super(context, inst.getFmri(), inst.getObjectName());
 
-	svcFmri_ = fmri_.toServiceFMRI();
-	state_ = inst.getState();
-	stime_ = inst.getSTime();
+	svcFmri = fmri.toServiceFMRI();
+	state = inst.getState();
+	stime = inst.getSTime();
     }
 
     @Override
-    public ManagedObjectStatus getStatus()
-    {
-	return (ServiceUtil.getPanelStatus(state_));
+    public ManagedObjectStatus getStatus() {
+	return ServiceUtil.getPanelStatus(state);
     }
 
     @Override
-    public String getStatusText()
-    {
-	return (ServiceUtil.getStateSynopsis(state_, null));
+    public String getStatusText() {
+	return ServiceUtil.getStateSynopsis(state, null);
     }
 
-    /*
-     * DepManagedObject methods
-     */
+    //
+    // DepManagedObject methods
+    //
 
     @Override
-    public String getDepType()
-    {
-	return (Finder.getString("smf.depend.type.instance"));
+    public String getDepType() {
+	return Finder.getString("smf.depend.type.instance");
     }
 
     @Override
-    public String getDepState()
-    {
-	return (ServiceUtil.getStateString(getSMFState()));
+    public String getDepState() {
+	return ServiceUtil.getStateString(getSMFState());
     }
 
-    /*
-     * NotificationListener methods
-     */
+    //
+    // NotificationListener methods
+    //
 
     /**
      * Handles changes to this {@code InstanceManagedObject}'s service.
@@ -90,43 +84,39 @@
      * fires a {@code PropertyChangeEvent} to registered {@code
      * PropertyChangeEvent}s.
      */
-    public void handleStateChange(StateChange sc)
-    {
-	SmfState oldState = state_;
-	state_ = sc.getState();
-	stime_ = sc.getStateTime();
+    public void handleStateChange(StateChange sc) {
+	SmfState oldState = state;
+	state = sc.getState();
+	stime = sc.getStateTime();
 	firePropertyChange(new PropertyChangeEvent(this, PROPERTY_STATE,
-	    oldState, state_));
+	    oldState, state));
     }
 
-    /*
-     * InstanceManagedObject methods
-     */
+    //
+    // InstanceManagedObject methods
+    //
 
-    public FMRI getServiceFmri()
-    {
-	return (svcFmri_);
+    public FMRI getServiceFmri() {
+	return svcFmri;
     }
 
-    public SmfState getSMFState()
-    {
-	return (state_);
+    public SmfState getSMFState() {
+	return state;
     }
 
-    public Date getLastChange()
-    {
-	return (stime_);
+    public Date getLastChange() {
+	return stime;
     }
 
-    public boolean isEnabled()
-    {
+    public boolean isEnabled() {
 	/* More or less true */
-	return (state_ != state_.DISABLED);
+	return state != state.DISABLED;
     }
 
-    public void setEnabled(boolean enable) throws ScfException
-    {
-	if (bean_ != null)
-	    bean_.setPersistentlyEnabled(enable);
+    public void setEnabled(boolean enable) throws ScfException {
+	ServiceMXBean bean = getService();
+	if (bean != null) {
+	    bean.setPersistentlyEnabled(enable);
+	}
     }
 }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/RepoManagedObject.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/RepoManagedObject.java	Wed Jul 21 20:26:39 2010 -0400
@@ -25,108 +25,82 @@
 
 package org.opensolaris.os.vp.panel.common.smf;
 
+import java.beans.*;
 import java.io.IOException;
 import java.util.*;
+import java.util.logging.*;
 import javax.management.*;
-import javax.management.remote.JMXConnector;
 import org.opensolaris.os.rad.ObjectException;
 import org.opensolaris.os.rad.jmx.RadNotification;
 import org.opensolaris.os.smf.*;
 import org.opensolaris.os.vp.common.panel.MBeanUtil;
-import org.opensolaris.os.vp.common.remotefile.*;
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.model.*;
+import org.opensolaris.os.vp.panel.common.remotefile.*;
 
 public class RepoManagedObject
-    extends AbstractManagedObject<InstanceManagedObject>
-    implements ConnectionListener, NotificationListener {
+    extends AbstractManagedObject<InstanceManagedObject> {
 
     //
     // Static data
     //
 
-    private static final ObjectName on =
+    private static final ObjectName oName =
 	MBeanUtil.makeObjectName("org.opensolaris.os.smf", "aggregator");
 
     //
     // Instance data
     //
 
-    private ClientContext context;
     private Set<Service> services;
     private Set<Instance> instances;
     private Map<ObjectName, SmfManagedObject> objects;
-    private MBeanServerConnection mbsc;
     private AbstractManagedObject<ServiceManagedObject> serviceMo;
 
+    private MXBeanTracker<AggregatorMXBean> beanTracker;
+
+    private NotificationListener stateListener =
+	new NotificationListener() {
+	    @Override
+	    public void handleNotification(Notification notification,
+		Object handback) {
+
+		StateChange sc = ((RadNotification)notification).getPayload(
+		    StateChange.class);
+		stateChanged(sc);
+	    }
+	};
+
+    private PropertyChangeListener beanListener =
+	new PropertyChangeListener() {
+	    @Override
+	    public void propertyChange(PropertyChangeEvent event) {
+		beanChanged();
+	    }
+	};
+
     //
     // Constructors
     //
 
-    public RepoManagedObject(String id, ClientContext context) {
+    public RepoManagedObject(String id, ClientContext context)
+	throws InstanceNotFoundException, IOException {
+
 	super(id);
 
-	this.context = context;
-	objects = new HashMap<ObjectName, SmfManagedObject>();
+	objects = Collections.emptyMap();
 	serviceMo = new AbstractManagedObject<ServiceManagedObject>() {};
-	newConnection(context.getConnectionInfo(), true);
-	context.addConnectionListener(this);
-    }
-
-    //
-    // ConnectionListener methods
-    //
 
-    @Override
-    public void connectionChanged(ConnectionEvent event) {
-	/*
-	 * Because we might need to navigate back to a particular service
-	 * or instance, we are unable to perform an asynchronous update
-	 * when the connection changes.
-	 *
-	 * In the future, we might consider doing a synchronous update
-	 * only if we are located at a service or instance panel, and then
-	 * perhaps only synchronously update that specific service or
-	 * instance.
-	 */
-	newConnection(event.getConnectionInfo(), false);
-    }
+	beanTracker = new MXBeanTracker<AggregatorMXBean>(
+	    AggregatorMXBean.class, context, oName);
 
-    @Override
-    public void connectionFailed(ConnectionEvent event) {
-	if (mbsc != null) {
-	    try {
-		mbsc.removeNotificationListener(on, this);
-
-	    // The connection is likely already closed
-	    } catch (Throwable ignore) {
-	    }
-
-	    mbsc = null;
-	}
-    }
-
-    //
-    // NotificationListener methods
-    //
+	beanTracker.addNotificationListener(stateListener,
+	    SmfUtil.NOTIFY_FILTER_STATE_CHANGE, null);
 
-    @Override
-    public void handleNotification(Notification notification, Object handback) {
-	if (!(notification instanceof RadNotification) ||
-	    !notification.getType().equals("statechange"))
-	    return;
+	beanTracker.addPropertyChangeListener(
+	    MXBeanTracker.PROPERTY_BEAN, beanListener);
 
-	RadNotification rn = (RadNotification)notification;
-	StateChange sc = rn.getPayload(StateChange.class);
-	if (sc == null) {
-	    return;
-	}
-
-	SmfManagedObject smo = objects.get(sc.getSource());
-	if (smo != null && smo instanceof InstanceManagedObject) {
-	    InstanceManagedObject imo = (InstanceManagedObject)smo;
-	    imo.handleStateChange(sc);
-	}
+	beanChanged();
     }
 
     //
@@ -134,97 +108,18 @@
     //
 
     /**
-     * Removes this {@code RepoManagedObject} as listeners.
+     * Stops monitoring the connection to the remote host.
      */
     @Override
     public void dispose() {
-	try {
-	    mbsc.removeNotificationListener(on, this);
-	} catch (Throwable ignore) {
-	}
-
-	try {
-	    context.removeConnectionListener(this);
-	} catch (Throwable ignore) {
-	}
-
+	beanTracker.dispose();
 	super.dispose();
     }
 
     //
-    // Private methods
+    // RepoManagedObject methods
     //
 
-    /**
-     * Called when switching to a new connection.  Permits selecting
-     * between synchronously or asynchronously updating the list of
-     * services.
-     *
-     * @param cinfo the new Connection
-     * @param async whether the update should occur asynchronously or not
-     */
-    private void newConnection(ConnectionInfo cinfo, final boolean async) {
-	if (mbsc != null) {
-	    try {
-		mbsc.removeNotificationListener(on, this);
-
-	    // If something prevented us from removing ourselves as a
-	    // notification listener, it probably doesn't matter anymore.
-	    } catch (Throwable ignore) {
-	    }
-	    mbsc = null;
-	}
-
-	try {
-	    mbsc = cinfo.getConnector().getMBeanServerConnection();
-	    AggregatorMXBean aggbean = JMX.newMXBeanProxy(mbsc, on,
-		AggregatorMXBean.class);
-	    mbsc.addNotificationListener(on, this, null, null);
-	    services = new HashSet<Service>(aggbean.getServices());
-	    instances = new HashSet<Instance>(aggbean.getInstances());
-	} catch (ObjectException e) {
-	} catch (IOException e) {
-	} catch (InstanceNotFoundException e) {
-	}
-
-	/*
-	 * Ideally, this would preserve those children which remain after a
-	 * relogin, and throw away children after a host change.
-	 *
-	 * Right now, it preserves objects but not the child list on both
-	 * relogin and host changes.
-	 */
-
-	clearChildren();
-	serviceMo.clearChildren();
-	Map<ObjectName, SmfManagedObject> oldobjs = objects;
-	objects = new HashMap<ObjectName, SmfManagedObject>(objects);
-
-	for (Service svc : services) {
-	    ServiceManagedObject smo =
-		(ServiceManagedObject)oldobjs.get(svc.getObjectName());
-	    if (smo != null) {
-		smo.reconnect(mbsc);
-	    }
-	    else
-		smo = new ServiceManagedObject(this, mbsc, svc);
-	    objects.put(smo.getObjectName(), smo);
-	    serviceMo.addChildren(smo);
-	}
-
-	for (Instance inst : instances) {
-	    InstanceManagedObject imo =
-		(InstanceManagedObject)oldobjs.get(inst.getObjectName());
-	    if (imo != null) {
-		imo.reconnect(mbsc);
-	    }
-	    else
-		imo = new InstanceManagedObject(mbsc, inst);
-	    objects.put(imo.getObjectName(), imo);
-	    addChildren(imo);
-	}
-    }
-
     public boolean hasInstance(String service) {
 	ObjectName pattern;
 
@@ -242,6 +137,10 @@
 	return false;
     }
 
+    public ConnectionTracker getConnectionTracker() {
+	return beanTracker;
+    }
+
     public ManagedObject<ServiceManagedObject> getServices() {
 	return serviceMo;
     }
@@ -265,13 +164,92 @@
     }
 
     public boolean fileExists(String filename) {
-	try {
-	    FileBrowserMXBean mb = JMX.newMXBeanProxy(mbsc,
-		FileBrowserUtil.OBJECT_NAME, FileBrowserMXBean.class);
-	    return mb.getFile(filename).isExists();
-	} catch (ObjectException e) {
-	    return false;
+	MBeanServerConnection mbsc = beanTracker.getMBeanServerConnection();
+	if (mbsc != null) {
+	    try {
+		FileBrowserMXBean mb = JMX.newMXBeanProxy(mbsc,
+		    FileBrowserUtil.OBJECT_NAME, FileBrowserMXBean.class);
+		return mb.getFile(filename).isExists();
+	    } catch (ObjectException e) {
+	    }
+	}
+	return false;
+    }
+
+    //
+    // Private methods
+    //
+
+    private void beanChanged() {
+	services = Collections.emptySet();
+	instances = Collections.emptySet();
+
+	AggregatorMXBean bean = beanTracker.getBean();
+	if (bean != null) {
+	    try {
+		services = new HashSet<Service>(bean.getServices());
+		instances = new HashSet<Instance>(bean.getInstances());
+	    } catch (ObjectException e) {
+		Logger.getLogger(getClass().getName()).log(Level.SEVERE,
+		    "could not retrieve smf services/instances", e);
+	    }
+	}
+
+	/*
+	 * Ideally, this would preserve those children that remain after a
+	 * relogin, and throw away children after a host change.
+	 *
+	 * Right now, it preserves objects but not the child list on both
+	 * relogin and host changes.
+	 */
 
+	clearChildren();
+	serviceMo.clearChildren();
+	Map<ObjectName, SmfManagedObject> oldObjects = objects;
+	objects = new HashMap<ObjectName, SmfManagedObject>(objects);
+
+	for (Service svc : services) {
+	    ObjectName oName = svc.getObjectName();
+            ServiceManagedObject smo =
+		(ServiceManagedObject)oldObjects.get(oName);
+	    if (smo == null) {
+                smo = new ServiceManagedObject(this,
+		    beanTracker.getClientContext(), svc);
+	    } else {
+		oldObjects.remove(oName);
+	    }
+
+	    objects.put(oName, smo);
+	    serviceMo.addChildren(smo);
+	}
+
+	for (Instance inst : instances) {
+	    ObjectName oName = inst.getObjectName();
+	    InstanceManagedObject imo =
+		(InstanceManagedObject)oldObjects.get(oName);
+	    if (imo == null) {
+                imo = new InstanceManagedObject(beanTracker.getClientContext(),
+		    inst);
+	    } else {
+		oldObjects.remove(oName);
+	    }
+
+	    objects.put(oName, imo);
+	    addChildren(imo);
+	}
+
+	// Ensure that any SmfManagedObjects for now-non-existent services are
+	// prepared for garbage collection
+	for (SmfManagedObject smo : oldObjects.values()) {
+	    smo.dispose();
+	}
+    }
+
+    private void stateChanged(StateChange sc) {
+	SmfManagedObject smo = objects.get(sc.getSource());
+	if (smo != null && smo instanceof InstanceManagedObject) {
+	    InstanceManagedObject imo = (InstanceManagedObject)smo;
+	    imo.handleStateChange(sc);
 	}
     }
 }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/ScfUtil.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.panel.common.smf;
-
-import org.opensolaris.os.scf.common.ScfException;
-import org.opensolaris.os.smf.SmfErrorCode;
-import org.opensolaris.os.vp.panel.common.action.*;
-import org.opensolaris.os.vp.util.misc.Finder;
-
-@SuppressWarnings({"serial"})
-public class ScfUtil extends Exception {
-    //
-    // Static methods
-    //
-
-    public static void throwActionException(ScfException e)
-	throws ActionFailedException, ActionUnauthorizedException {
-
-	if (e.getError() == SmfErrorCode.PERMISSION_DENIED) {
-	    throw new ActionUnauthorizedException(e);
-	}
-
-	throw new ActionFailedException(
-	    Finder.getString("error.repository.write"), e);
-    }
-}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/ServiceManagedObject.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/ServiceManagedObject.java	Wed Jul 21 20:26:39 2010 -0400
@@ -26,8 +26,8 @@
 package org.opensolaris.os.vp.panel.common.smf;
 
 import java.util.Date;
-import javax.management.MBeanServerConnection;
 import org.opensolaris.os.smf.*;
+import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.model.ManagedObjectStatus;
 import org.opensolaris.os.vp.util.misc.Finder;
 
@@ -36,10 +36,10 @@
     private Service sdesc_;
     private RepoManagedObject repo_;
 
-    ServiceManagedObject(RepoManagedObject repo, MBeanServerConnection mbsc,
+    ServiceManagedObject(RepoManagedObject repo, ClientContext context,
 	Service svc)
     {
-	super(mbsc, svc.getFmri(), svc.getObjectName());
+	super(context, svc.getFmri(), svc.getObjectName());
 	repo_ = repo;
 	sdesc_ = svc;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/ServiceTracker.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,117 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.smf;
+
+import java.beans.*;
+import java.io.IOException;
+import javax.management.*;
+import org.opensolaris.os.smf.ServiceInfoMXBean;
+import org.opensolaris.os.vp.panel.common.*;
+
+/**
+ * The {@code ServiceTracker} is a {@link MXBeanTracker} that automatically
+ * creates and re-creates an {@link #getService AggregatedRefreshService}, which
+ * wraps a {@link ServiceMXBeanAdaptor}, which wraps a {@link
+ * ServiceInfoMXBean}.
+ */
+public class ServiceTracker extends MXBeanTracker<ServiceInfoMXBean> {
+    //
+    // Static data
+    //
+
+    /**
+     * The name of the property that changes with {@link #setService}.
+     */
+    public static final String PROPERTY_SERVICE = "service";
+
+    //
+    // Instance data
+    //
+
+    private AggregatedRefreshService service;
+
+    private PropertyChangeListener beanListener =
+	new PropertyChangeListener() {
+	    @Override
+	    public void propertyChange(PropertyChangeEvent event) {
+		setService();
+	    }
+	};
+
+    //
+    // Constructors
+    //
+
+    public ServiceTracker() {
+	this(null, null);
+    }
+
+    public ServiceTracker(ClientContext context, ObjectName oName) {
+	super(ServiceInfoMXBean.class, context, oName);
+
+	addPropertyChangeListener(PROPERTY_BEAN, beanListener);
+	setService();
+    }
+
+    public ServiceTracker(ClientContext context, String serviceName,
+	String instanceName) {
+
+	this(context, ServiceUtil.toObjectName(serviceName, instanceName));
+    }
+
+    //
+    // ServiceTracker methods
+    //
+
+    public AggregatedRefreshService getService() {
+	return service;
+    }
+
+    public void setObjectName(String serviceName, String instanceName)
+        throws InstanceNotFoundException, IOException {
+
+	ObjectName oName = ServiceUtil.toObjectName(serviceName, instanceName);
+	setObjectName(oName);
+    }
+
+    protected void setService(AggregatedRefreshService service) {
+	if (this.service != service) {
+	    PropertyChangeEvent e = new PropertyChangeEvent(
+		this, PROPERTY_SERVICE, this.service, service);
+	    this.service = service;
+	    getPropertyChangeListeners().propertyChange(e);
+	}
+    }
+
+    //
+    // Private methods
+    //
+
+    private void setService() {
+	setService(new AggregatedRefreshService(new ServiceMXBeanAdaptor(
+	    getBean())));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleHasService.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,51 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.smf;
+
+public class SimpleHasService implements HasService {
+    //
+    // Instance data
+    //
+
+    private ServiceMXBean service;
+
+    //
+    // Constructors
+    //
+
+    public SimpleHasService(ServiceMXBean service) {
+	this.service = service;
+    }
+
+    //
+    // HasService methods
+    //
+
+    @Override
+    public ServiceMXBean getService() {
+	return service;
+    }
+}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfPropertyGroupInfo.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfPropertyGroupInfo.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panel.common.smf;
@@ -33,25 +32,24 @@
     // Instance data
     //
 
-    private SmfServiceInfo info;
+    private HasService info;
     private String group;
 
     //
     // Constructors
     //
 
-    public SimpleSmfPropertyGroupInfo(SmfServiceInfo info, String group)
-    {
+    public SimpleSmfPropertyGroupInfo(HasService info, String group) {
 	this.info = info;
 	this.group = group;
     }
 
     public SimpleSmfPropertyGroupInfo(ServiceMXBean service, String group) {
-	this(new SimpleSmfServiceInfo(service), group);
+	this(new SimpleHasService(service), group);
     }
 
     //
-    // SmfServiceInfo methods
+    // HasService methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfPropertyInfo.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfPropertyInfo.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panel.common.smf;
@@ -45,18 +44,18 @@
 	this.name = name;
     }
 
-    public SimpleSmfPropertyInfo(SmfServiceInfo info, String group, String name)
+    public SimpleSmfPropertyInfo(HasService info, String group, String name)
     {
 	this(new SimpleSmfPropertyGroupInfo(info, group), name);
     }
 
     public SimpleSmfPropertyInfo(ServiceMXBean service, String group,
 	String name) {
-	this(new SimpleSmfServiceInfo(service), group, name);
+	this(new SimpleHasService(service), group, name);
     }
 
     //
-    // SmfServiceInfo methods
+    // HasService methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SimpleSmfServiceInfo.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.panel.common.smf;
-
-public class SimpleSmfServiceInfo implements SmfServiceInfo {
-    //
-    // Instance data
-    //
-
-    private ServiceMXBean service;
-
-    //
-    // Constructors
-    //
-
-    public SimpleSmfServiceInfo(ServiceMXBean service) {
-	this.service = service;
-    }
-
-    //
-    // SmfServiceInfo methods
-    //
-
-    @Override
-    public ServiceMXBean getService() {
-	return service;
-    }
-}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfEnabledProperty.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfEnabledProperty.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panel.common.smf;
@@ -49,7 +48,7 @@
     // Instance data
     //
 
-    private SmfServiceInfo info;
+    private HasService info;
 
     //
     // Constructors
@@ -64,7 +63,7 @@
      * @param	    info
      *		    source of the service
      */
-    public SmfEnabledProperty(String name, SmfServiceInfo info) {
+    public SmfEnabledProperty(String name, HasService info) {
 	super(name);
 	this.info = info;
     }
@@ -76,7 +75,7 @@
      * @param	    info
      *		    source of the service
      */
-    public SmfEnabledProperty(SmfServiceInfo info) {
+    public SmfEnabledProperty(HasService info) {
 	this(NAME, info);
     }
 
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfManagedObject.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfManagedObject.java	Wed Jul 21 20:26:39 2010 -0400
@@ -27,18 +27,19 @@
 
 import java.net.URISyntaxException;
 import java.util.*;
-import javax.management.*;
+import javax.management.ObjectName;
 import javax.swing.*;
 import org.opensolaris.os.scf.common.*;
-import org.opensolaris.os.smf.*;
+import org.opensolaris.os.smf.Dependency;
+import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.model.ManagedObject;
 import org.opensolaris.os.vp.panel.common.smf.depend.DepManagedObject;
 import org.opensolaris.os.vp.util.misc.*;
 import org.opensolaris.os.vp.util.swing.HasIcon;
 
 public abstract class SmfManagedObject extends DepManagedObject<ManagedObject>
-    implements SmfServiceInfo, HasIcon, Comparable<SmfManagedObject>
-{
+    implements HasService, HasIcon, Comparable<SmfManagedObject> {
+
     //
     // Static data
     //
@@ -56,29 +57,37 @@
     // Instance data
     //
 
-    protected AggregatedRefreshService bean_;
-    protected ObjectName on_;
-    protected FMRI fmri_;
-    protected String name_;
-    protected String desc_;
-    protected Map<String, Dependency> dependencies_;
-    protected String serviceName_;
+    protected ServiceTracker tracker;
+    protected ObjectName on;
+    protected FMRI fmri;
+    protected String name;
+    protected String desc;
+    protected Map<String, Dependency> dependencies;
+    protected String serviceName;
 
     //
     // Constructors
     //
 
-    SmfManagedObject(MBeanServerConnection mbsc, String fmri, ObjectName on)
-    {
-	bean_ = new AggregatedRefreshService(new ServiceMXBeanAdaptor(
-	    JMX.newMXBeanProxy(mbsc, on, ServiceInfoMXBean.class)));
+    public SmfManagedObject(ClientContext context, String fmri, ObjectName on) {
+	tracker = new ServiceTracker(context, on);
+
 	try {
-	    fmri_ = new FMRI(fmri);
+	    this.fmri = new FMRI(fmri);
 	} catch (URISyntaxException e) {
-	    fmri_ = null;
+	    this.fmri = null;
 	}
-	on_ = on;
-	serviceName_ = ServiceUtil.toService(on);
+	this.on = on;
+	serviceName = ServiceUtil.toService(on);
+    }
+
+    //
+    // Comparable methods
+    //
+
+    @Override
+    public int compareTo(SmfManagedObject o) {
+	return fmri.compareTo(o.fmri);
     }
 
     //
@@ -95,9 +104,17 @@
     //
 
     @Override
-    public String getId()
-    {
-	return (fmri_.toString());
+    public String getId() {
+	return fmri.toString();
+    }
+
+    //
+    // HasService methods
+    //
+
+    @Override
+    public AggregatedRefreshService getService() {
+	return tracker.getService();
     }
 
     //
@@ -105,9 +122,14 @@
     //
 
     @Override
-    public String getName()
-    {
-	return (fmri_.toString());
+    public void dispose() {
+	tracker.dispose();
+	super.dispose();
+    }
+
+    @Override
+    public String getName() {
+	return fmri.toString();
     }
 
     //
@@ -115,88 +137,69 @@
     //
 
     @Override
-    public String getDepName()
-    {
-	return (getSMFFmri().toString());
-    }
-
-    //
-    // SmfServiceInfo methods
-    //
-
-    @Override
-    public AggregatedRefreshService getService() {
-	return bean_;
+    public String getDepName() {
+	return getSMFFmri().toString();
     }
 
     //
     // SmfManagedObject methods
     //
 
-    public FMRI getSMFFmri()
-    {
-	return (fmri_);
+    public FMRI getSMFFmri() {
+	return fmri;
     }
 
-    public String getSMFName()
-    {
+    public String getSMFName() {
 	synchronized (this) {
-	    if (name_ != null)
-		return (name_);
+	    if (name != null) {
+		return name;
+	    }
 
 	    try {
-		name_ = bean_.getCommonName(Locale.getDefault().getLanguage());
+		name = getService().getCommonName(
+		    Locale.getDefault().getLanguage());
 	    } catch (ScfException e) {
 	    }
-	    return (name_);
-	}
-    }
-
-    public String getSMFDesc()
-    {
-	synchronized (this) {
-	    if (desc_ != null)
-		return (desc_);
-
-	    try {
-		desc_ = bean_.getCommonName(Locale.getDefault().getLanguage());
-	    } catch (ScfException e) {
-	    }
-	    return (desc_);
+	    return name;
 	}
     }
 
-    public Collection<Dependency> getDependencies()
-    {
+    public String getSMFDesc() {
 	synchronized (this) {
-	    if (dependencies_ != null)
-		return (dependencies_.values());
+	    if (desc != null) {
+		return desc;
+	    }
 
 	    try {
-		dependencies_ = new HashMap<String, Dependency>();
-		List<String> deps = bean_.getDependencyNames();
-		for (String dep : deps)
-		    dependencies_.put(dep, bean_.getDependency(dep));
+		desc = getService().getCommonName(
+		    Locale.getDefault().getLanguage());
+	    } catch (ScfException e) {
+	    }
+	    return desc;
+	}
+    }
+
+    public Collection<Dependency> getDependencies() {
+	synchronized (this) {
+	    if (dependencies != null) {
+		return dependencies.values();
+	    }
+
+	    try {
+		dependencies = new HashMap<String, Dependency>();
+		ServiceMXBean service = getService();
+		List<String> deps = service.getDependencyNames();
+		for (String dep : deps) {
+		    dependencies.put(dep, service.getDependency(dep));
+		}
 	    } catch (ScfException e) {
 	    }
 
-	    return (dependencies_.values());
+	    return dependencies.values();
 	}
     }
 
-    public ObjectName getObjectName()
-    {
-	return (on_);
-    }
-
-    public void reconnect(MBeanServerConnection mbsc)
-    {
-	bean_ = mbsc == null ? null : new AggregatedRefreshService(
-	    new ServiceMXBeanAdaptor(JMX.newMXBeanProxy(mbsc, on_,
-	    ServiceInfoMXBean.class)));
-    }
-
-    public int compareTo(SmfManagedObject o) {
-	return (fmri_.compareTo(o.fmri_));
+    public ObjectName getObjectName() {
+	return on;
     }
 }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfPropertyGroupInfo.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfPropertyGroupInfo.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,15 +20,14 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panel.common.smf;
 
 import org.opensolaris.os.scf.common.ScfException;
 
-public interface SmfPropertyGroupInfo extends SmfServiceInfo {
+public interface SmfPropertyGroupInfo extends HasService {
     /**
      * Gets the SMF property group name.
      *
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfServiceInfo.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.panel.common.smf;
-
-public interface SmfServiceInfo {
-    /**
-     * Gets the service.
-     */
-    ServiceMXBean getService();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/smf/SmfUtil.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,64 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.smf;
+
+import javax.management.*;
+import org.opensolaris.os.rad.jmx.RadNotification;
+import org.opensolaris.os.scf.common.ScfException;
+import org.opensolaris.os.smf.*;
+import org.opensolaris.os.vp.panel.common.action.*;
+import org.opensolaris.os.vp.util.misc.Finder;
+
+public class SmfUtil {
+    //
+    // Static data
+    //
+
+    public static final NotificationFilter NOTIFY_FILTER_STATE_CHANGE =
+	new NotificationFilter() {
+	    @Override
+	    public boolean isNotificationEnabled(Notification n) {
+		return n instanceof RadNotification &&
+		    n.getType().equals("statechange") &&
+		    ((RadNotification)n).getPayload(StateChange.class) != null;
+	    }
+	};
+
+    //
+    // Static methods
+    //
+
+    public static void throwActionException(ScfException e)
+	throws ActionFailedException, ActionUnauthorizedException {
+
+	if (e.getError() == SmfErrorCode.PERMISSION_DENIED) {
+	    throw new ActionUnauthorizedException(e);
+	}
+
+	throw new ActionFailedException(
+	    Finder.getString("error.repository.write"), e);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/time/HasTimeMXBean.java	Wed Jul 21 20:26:39 2010 -0400
@@ -0,0 +1,30 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+package org.opensolaris.os.vp.panel.common.time;
+
+public interface HasTimeMXBean {
+    TimeMXBean getTimeMXBean();
+}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ClearServiceAction.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ClearServiceAction.java	Wed Jul 21 20:26:39 2010 -0400
@@ -81,7 +81,7 @@
 	    try {
 		inst.getService().clear();
 	    } catch (ScfException e) {
-		ScfUtil.throwActionException(e);
+		SmfUtil.throwActionException(e);
 	    } catch (SecurityException e) {
 		throw new ActionUnauthorizedException(e);
 	    }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/EnableServiceAction.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/EnableServiceAction.java	Wed Jul 21 20:26:39 2010 -0400
@@ -79,7 +79,7 @@
 	    try {
 		inst.setEnabled(enable);
 	    } catch (ScfException e) {
-		ScfUtil.throwActionException(e);
+		SmfUtil.throwActionException(e);
 	    } catch (SecurityException e) {
 		throw new ActionUnauthorizedException(e);
 	    }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceSettingsPanel.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceSettingsPanel.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panel.swing.smf;
@@ -30,10 +29,10 @@
 import java.util.*;
 import javax.swing.*;
 import javax.swing.border.Border;
-import org.opensolaris.os.scf.common.*;
+import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.smf.*;
 import org.opensolaris.os.vp.panel.common.smf.*;
-import org.opensolaris.os.vp.panel.swing.view.*;
+import org.opensolaris.os.vp.panel.swing.view.ChangeIndicator;
 import org.opensolaris.os.vp.util.misc.*;
 import org.opensolaris.os.vp.util.swing.*;
 import org.opensolaris.os.vp.util.swing.layout.*;
@@ -62,8 +61,8 @@
 	AUTH_PROPS.add(AUTH_READ);
     }
 
-    private boolean empty_ = true;
-    private SmfServiceInfo serviceInfo;
+    private boolean empty = true;
+    private HasService serviceInfo;
 
     //
     // Constructors
@@ -72,13 +71,11 @@
     public ServiceSettingsPanel() {
     }
 
-    public boolean isEmpty()
-    {
-	return (empty_);
+    public boolean isEmpty() {
+	return empty;
     }
 
-    public void init(SmfServiceInfo serviceInfo) throws ScfException
-    {
+    public void init(HasService serviceInfo) throws ScfException {
 	this.serviceInfo = serviceInfo;
 	JPanel form = createForm();
 	setContent(form);
@@ -98,7 +95,7 @@
 	tabui.setDrawContentBorder(true);
 	tabs.setUI(tabui);
 
-	Border empty = GUIUtil.getEmptyBorder();
+	Border emptyBorder = GUIUtil.getEmptyBorder();
 	int gap = GUIUtil.getHalfGap();
 
 	ColumnLayoutConstraint c = new ColumnLayoutConstraint(
@@ -114,14 +111,15 @@
 	pgs.addAll(service.getPropertyGroups());
 	Collections.sort(pgs, new Comparator<PropertyGroup>() {
 	    public int compare(PropertyGroup o1, PropertyGroup o2) {
-		return (o1.getName().compareTo(o2.getName()));
+		return o1.getName().compareTo(o2.getName());
 	    }
 	});
 
 
 	for (PropertyGroup pg : pgs) {
-	    if (!pg.getType().equals("application"))
+	    if (!pg.getType().equals("application")) {
 		continue;
+	    }
 
 	    String pgName = pg.getName();
 
@@ -133,8 +131,9 @@
 	    Form form = null;
 
 	    for (String pName : pNames) {
-		if (AUTH_PROPS.contains(pName))
+		if (AUTH_PROPS.contains(pName)) {
 		    continue;
+		}
 
 		// XXX Should be a static final somewhere
 		if (pName.equals("stability")) {
@@ -156,15 +155,16 @@
 		 * There are a number of different ways to treat unreadable
 		 * properties.  For now we just won't display them.
 		 */
-		if (!view.property.isReadable())
+		if (!view.property.isReadable()) {
 		    continue;
+		}
 
 		if (formPanel == null) {
 		    formPanel = new JPanel();
 		    formPanel.setOpaque(true);
 		    formPanel.setBackground(
 			ColorUtil.darker(getBackground(), .05f));
-		    formPanel.setBorder(empty);
+		    formPanel.setBorder(emptyBorder);
 
 		    form = new Form(formPanel, VerticalAnchor.TOP);
 		    form.addTable(3, gap, gap, HorizontalAnchor.FILL, c);
@@ -191,7 +191,7 @@
 	panel.setOpaque(false);
 
 	// If no properties were found...
-	if (empty_ = (tabs.getTabCount() == 0)) {
+	if (empty = (tabs.getTabCount() == 0)) {
 	    JLabel label = new JLabel(Finder.getString(
 		"service.settings.nosettings.label"));
 
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceStatusControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceStatusControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -27,10 +27,10 @@
 
 import java.awt.Component;
 import java.io.IOException;
-import java.util.logging.Level;
-import javax.management.*;
-import org.opensolaris.os.vp.panel.common.ClientContext;
+import java.util.logging.*;
+import javax.management.InstanceNotFoundException;
 import org.opensolaris.os.vp.panel.common.model.PanelDescriptor;
+import org.opensolaris.os.vp.panel.common.smf.*;
 import org.opensolaris.os.vp.panel.swing.control.SwingSettingsControl;
 import org.opensolaris.os.vp.util.misc.Finder;
 
@@ -50,19 +50,15 @@
     // Instance data
     //
 
-    private ObjectName oName;
+    private HasServiceTracker hasTracker;
 
     //
     // Constructors
     //
 
-    public ServiceStatusControl(P descriptor) {
+    public ServiceStatusControl(P descriptor, HasServiceTracker hasTracker) {
 	super(ID, NAME, descriptor);
-    }
-
-    public ServiceStatusControl(P descriptor, ObjectName oName) {
-	this(descriptor);
-	setObjectName(oName);
+	this.hasTracker = hasTracker;
     }
 
     //
@@ -76,39 +72,32 @@
 
     @Override
     protected void deinitComponent() {
-	ServiceStatusPanel panel = getComponent();
-	try {
-	    panel.setClientContext(null);
-	    panel.setObjectName(null);
-	} catch (IOException e) {
-	    getLog().log(Level.SEVERE, "could not deinitialize status", e);
-	} catch (InstanceNotFoundException e) {
-	    getLog().log(Level.SEVERE, "could not deinitialize status", e);
-	}
+	doInit(null);
     }
 
     @Override
     protected void initComponent() {
-	ServiceStatusPanel panel = getComponent();
-	try {
-	    panel.setClientContext(getPanelDescriptor().getClientContext());
-	    panel.setObjectName(oName);
-	} catch (IOException e) {
-	    getLog().log(Level.SEVERE, "could not initialize status", e);
-	} catch (InstanceNotFoundException e) {
-	    getLog().log(Level.SEVERE, "could not initialize status", e);
-	}
+	doInit(hasTracker.getServiceTracker());
     }
 
     //
-    // ServiceStatusControl methods
+    // Private methods
     //
 
-    public ObjectName getObjectName() {
-	return oName;
-    }
+    private void doInit(ServiceTracker tracker) {
+	Exception t = null;
 
-    public void setObjectName(ObjectName oName) {
-	this.oName = oName;
+	try {
+	    getComponent().init(tracker);
+	} catch (InstanceNotFoundException e) {
+	    t = e;
+	} catch (IOException e) {
+	    t = e;
+	}
+
+	if (t != null) {
+	    Logger.getLogger(getClass().getPackage().getName()).log(
+		Level.SEVERE, "error instantiating status component", t);
+	}
     }
 }
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceStatusPanel.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceStatusPanel.java	Wed Jul 21 20:26:39 2010 -0400
@@ -27,6 +27,7 @@
 
 import java.awt.*;
 import java.awt.event.*;
+import java.beans.*;
 import java.io.IOException;
 import java.util.*;
 import java.util.logging.*;
@@ -35,16 +36,13 @@
 import org.opensolaris.os.rad.jmx.RadNotification;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.smf.*;
-import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.smf.*;
 import org.opensolaris.os.vp.util.misc.*;
 import org.opensolaris.os.vp.util.swing.*;
 import org.opensolaris.os.vp.util.swing.layout.*;
 
 @SuppressWarnings({"serial"})
-public class ServiceStatusPanel extends SettingsPanel
-    implements ConnectionListener, NotificationListener {
-
+public class ServiceStatusPanel extends SettingsPanel {
     //
     // Inner classes
     //
@@ -71,10 +69,7 @@
     // Instance data
     //
 
-    private ClientContext context;
-    private MBeanServerConnection mbsc;
-    private ObjectName oName;
-    private ServiceMXBean service;
+    private ServiceTracker tracker;
 
     private JLabel statusLabel;
     private JTextArea statusArea;
@@ -97,6 +92,33 @@
     private JLabel descLabel;
     private JTextArea descArea;
 
+    private PropertyChangeListener serviceListener =
+	new PropertyChangeListener() {
+	    @Override
+	    public void propertyChange(PropertyChangeEvent event) {
+		serviceChanged();
+	    }
+	};
+
+    private NotificationListener notifyListener =
+	new NotificationListener() {
+	    @Override
+	    public void handleNotification(Notification n, Object h) {
+		final StateChange sc =
+		    ((RadNotification)n).getPayload(StateChange.class);
+
+		EventQueue.invokeLater(
+		    new Runnable() {
+			@Override
+			public void run() {
+			    setServiceState(sc.getState(),
+				sc.getNextState(), sc.getAuxState(),
+				sc.getStateTime());
+			}
+		    });
+	    }
+	};
+
     //
     // Constructors
     //
@@ -107,68 +129,6 @@
     }
 
     //
-    // ConnectionListener methods
-    //
-
-    @Override
-    public void connectionChanged(ConnectionEvent event) {
-	Exception e = null;
-	ConnectionInfo info = event.getConnectionInfo();
-
-	try {
-	    setConnectionInfo(info);
-	} catch (InstanceNotFoundException ex) {
-	    e = ex;
-	} catch (IOException ex) {
-	    e = ex;
-	}
-
-	if (e != null) {
-	    Logger.getLogger(getClass().getPackage().getName()).log(
-		Level.SEVERE, Finder.getString("error.jmx.general"), e);
-	}
-    }
-
-    @Override
-    public void connectionFailed(ConnectionEvent event) {
-	if (mbsc != null) {
-	    try {
-		mbsc.removeNotificationListener(oName, this);
-
-	    // The connection is likely already closed
-	    } catch (Throwable ignore) {
-	    }
-
-	    mbsc = null;
-	}
-    }
-
-    //
-    // NotificationListener methods
-    //
-
-    @Override
-    public void handleNotification(Notification n, Object h) {
-	if (!(n instanceof RadNotification) ||
-	    !n.getType().equals("statechange"))
-	    return;
-
-	final StateChange sc =
-	    ((RadNotification)n).getPayload(StateChange.class);
-
-	if (sc != null) {
-	    EventQueue.invokeLater(
-		new Runnable() {
-		    @Override
-		    public void run() {
-			setServiceState(sc.getState(), sc.getNextState(),
-			    sc.getAuxState(), sc.getStateTime());
-		    }
-		});
-	}
-    }
-
-    //
     // ServiceStatusPanel methods
     //
 
@@ -204,10 +164,10 @@
 	taskPanel.add(clearDegraded.getComponent());
 	taskPanel.add(enable.getComponent());
 	taskPanel.add(disable.getComponent());
-//	taskPanel.add(refresh.getComponent());
-//	taskPanel.add(restart.getComponent());
-//	taskPanel.add(maintain.getComponent());
-//	taskPanel.add(degrade.getComponent());
+	taskPanel.add(refresh.getComponent());
+	taskPanel.add(restart.getComponent());
+	taskPanel.add(maintain.getComponent());
+	taskPanel.add(degrade.getComponent());
 
 	JPanel panel = new JPanel();
 	panel.setOpaque(false);
@@ -227,45 +187,14 @@
 	return panel;
     }
 
-    /**
-     * Removes this {@code ServiceStatusPanel} as a {@code NotificationListener}
-     * for changes to its service.
-     */
-    public void dispose() {
-	context.removeConnectionListener(this);
-
-	try {
-	    mbsc.removeNotificationListener(oName, this);
-	} catch (Throwable e) {
-	    Logger.getLogger(getClass().getPackage().getName()).log(
-		Level.SEVERE, Finder.getString("error.jmx.general"), e);
-	}
-    }
-
-    public ClientContext getClientContext() {
-	return context;
-    }
-
-    public MBeanServerConnection getMBeanServerConnection() {
-	return mbsc;
-    }
-
-    public ObjectName getObjectName() {
-	return oName;
-    }
-
-    public ServiceMXBean getService() {
-	return service;
+    public HyperlinkLabel getClearDegradedLink() {
+        return clearDegraded.getLabel();
     }
 
     public HyperlinkLabel getClearMaintLink() {
 	return clearMaint.getLabel();
     }
 
-    public HyperlinkLabel getClearDegradedLink() {
-        return clearDegraded.getLabel();
-    }
-
     public HyperlinkLabel getDegradeLink() {
         return degrade.getLabel();
     }
@@ -290,30 +219,27 @@
         return restart.getLabel();
     }
 
-    public void setClientContext(ClientContext context)
-	throws IOException, InstanceNotFoundException {
-
-	this.context = context;
+    public void init(ServiceTracker tracker)
+	throws InstanceNotFoundException, IOException {
 
-	setConnectionInfo(context == null ? null : context.getConnectionInfo());
-	if (context != null) {
-	    context.addConnectionListener(this);
-	}
-    }
-
-    public void setObjectName(ObjectName oName)
-	throws IOException, InstanceNotFoundException {
-
-	if (!ObjectUtil.equals(oName, this.oName)) {
-	    if (mbsc != null && this.oName != null) {
-		try {
-		    mbsc.removeNotificationListener(this.oName, this);
-		} catch (Exception ignore) {
-		}
+	if (this.tracker != tracker) {
+	    if (this.tracker != null) {
+		this.tracker.removePropertyChangeListener(
+		    ServiceTracker.PROPERTY_SERVICE, serviceListener);
+                this.tracker.removeNotificationListener(notifyListener,
+		    SmfUtil.NOTIFY_FILTER_STATE_CHANGE, null);
 	    }
 
-	    this.oName = oName;
-	    setService();
+	    this.tracker = tracker;
+
+	    if (tracker != null) {
+		tracker.addPropertyChangeListener(
+		    ServiceTracker.PROPERTY_SERVICE, serviceListener);
+                tracker.addNotificationListener(notifyListener,
+		    SmfUtil.NOTIFY_FILTER_STATE_CHANGE, null);
+	    }
+
+	    serviceChanged();
 	}
     }
 
@@ -378,7 +304,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().clear();
+		    tracker.getService().clear();
 		}
 	    });
     }
@@ -390,7 +316,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().clear();
+		    tracker.getService().clear();
 		}
 	    });
     }
@@ -402,7 +328,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().degrade(true);
+		    tracker.getService().degrade(true);
 		}
 	    });
     }
@@ -414,7 +340,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().setPersistentlyEnabled(false);
+		    tracker.getService().setPersistentlyEnabled(false);
 		}
 	    });
     }
@@ -426,7 +352,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().setPersistentlyEnabled(true);
+		    tracker.getService().setPersistentlyEnabled(true);
 		}
 	    });
     }
@@ -438,7 +364,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().maintain(true);
+		    tracker.getService().maintain(true);
 		}
 	    });
     }
@@ -450,7 +376,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().refresh();
+		    tracker.getService().refresh();
 		}
 	    });
     }
@@ -462,7 +388,7 @@
 	    new SCFRunnable() {
 		@Override
 		protected void runScf() throws ScfException {
-		    getService().restart();
+		    tracker.getService().restart();
 		}
 	    });
     }
@@ -478,42 +404,8 @@
 	return new FlowTextArea();
     }
 
-    private void setConnectionInfo(ConnectionInfo info)
-	throws InstanceNotFoundException, IOException {
-
-	if (mbsc != null) {
-	    try {
-		mbsc.removeNotificationListener(oName, this);
-
-	    // If something prevented us from removing ourselves as a
-	    // notification listener, it probably doesn't matter anymore.
-	    } catch (Throwable ignore) {
-	    }
-	    mbsc = null;
-	}
-
-	if (info != null) {
-	    mbsc = info.getConnector().getMBeanServerConnection();
-	}
-
-	setService();
-    }
-
-    private void setService() throws IOException, InstanceNotFoundException {
-	ServiceMXBean service = null;
-
-	if (oName != null && mbsc != null) {
-	    mbsc.addNotificationListener(oName, this, null, null);
-
-	    service = new ServiceMXBeanAdaptor(JMX.newMXBeanProxy(
-		mbsc, oName, ServiceInfoMXBean.class));
-	}
-
-	setService(service);
-    }
-
-    private void setService(ServiceMXBean service) {
-	this.service = service;
+    private void serviceChanged() {
+	ServiceMXBean service = tracker == null ? null : tracker.getService();
 
 	Logger log = Logger.getLogger(getClass().getPackage().getName());
 
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceSwingPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/smf/ServiceSwingPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -29,7 +29,7 @@
 import java.io.IOException;
 import java.util.*;
 import java.util.logging.Level;
-import javax.management.*;
+import javax.management.InstanceNotFoundException;
 import javax.swing.Icon;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.smf.PropertyGroup;
@@ -133,9 +133,8 @@
     protected ServiceStatusControl<ServiceSwingPanelDescriptor>
 	createStatusControl() {
 
-	ObjectName oName = getObjectName();
 	return new ServiceStatusControl<ServiceSwingPanelDescriptor>(this,
-	    oName);
+	    this);
     }
 
     protected ServiceSettingsControl getSettingsControl() throws ScfException {
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/timezone/HasTimeZoneMXBean.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-package org.opensolaris.os.vp.panel.swing.timezone;
-
-import org.opensolaris.os.vp.panel.common.time.TimeMXBean;
-
-public interface HasTimeZoneMXBean {
-    TimeMXBean getTimeZoneMXBean();
-}
--- a/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/timezone/TimeZoneModel.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/swing/timezone/TimeZoneModel.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panel.swing.timezone;
@@ -29,9 +28,10 @@
 import org.opensolaris.os.rad.ObjectException;
 import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.model.AbstractModel;
+import org.opensolaris.os.vp.panel.common.time.HasTimeMXBean;
 import org.opensolaris.os.vp.util.misc.Finder;
 
-public class TimeZoneModel extends AbstractModel<HasTimeZoneMXBean> {
+public class TimeZoneModel extends AbstractModel<HasTimeMXBean> {
     //
     // Instance data
     //
@@ -43,7 +43,7 @@
     // Constructors
     //
 
-    public TimeZoneModel(HasTimeZoneMXBean descriptor) {
+    public TimeZoneModel(HasTimeMXBean descriptor) {
 	super(descriptor);
     }
 
@@ -67,7 +67,7 @@
 
     public void load() {
 	try {
-	    setTimeZone(getSource().getTimeZoneMXBean().getDefaultTimeZone());
+	    setTimeZone(getSource().getTimeMXBean().getDefaultTimeZone());
 	} catch (ObjectException e) {
 	    setTimeZone("UTC");
 	}
@@ -80,7 +80,7 @@
 	validate();
 
 	try {
-	    getSource().getTimeZoneMXBean().setDefaultTimeZone(timeZone);
+	    getSource().getTimeMXBean().setDefaultTimeZone(timeZone);
 
 	} catch (SecurityException e) {
 	    throw new ActionUnauthorizedException(e);
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ApacheInfo.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ApacheInfo.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.apache.client.swing;
@@ -30,7 +29,7 @@
 
 public interface ApacheInfo extends SmfPropertyInfo {
     //
-    // SmfServiceInfo methods
+    // HasService methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ApachePanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/ApachePanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -27,17 +27,16 @@
 
 import java.io.IOException;
 import java.util.*;
-import java.util.logging.Level;
-import javax.management.*;
+import javax.management.InstanceNotFoundException;
 import javax.swing.*;
 import javax.swing.filechooser.FileSystemView;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.smf.PropertyGroup;
-import org.opensolaris.os.vp.common.remotefile.RemoteFileSystemView;
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.control.*;
-import org.opensolaris.os.vp.panel.common.model.PanelDescriptor;
+import org.opensolaris.os.vp.panel.common.model.*;
 import org.opensolaris.os.vp.panel.common.network.*;
+import org.opensolaris.os.vp.panel.common.remotefile.RemoteFileSystemView;
 import org.opensolaris.os.vp.panel.common.smf.*;
 import org.opensolaris.os.vp.panel.swing.control.PanelFrameControl;
 import org.opensolaris.os.vp.panel.swing.smf.ServiceSwingPanelDescriptor;
@@ -73,7 +72,8 @@
     //
 
     private DefaultControl control;
-    private FileSystemView fsView;
+    private RemoteFileSystemView fsView;
+    private MXBeanTracker<NetworkMXBean> networkBeanTracker;
 
     private BasicSmfMutableProperty<Boolean> customEnabledProperty =
 	new BooleanSmfProperty(PROPERTY_CUSTOM_ENABLED, this);
@@ -94,8 +94,6 @@
     private PropertyGroupNamePool vHostNamePool;
     private List<VirtualHost> removed = new ArrayList<VirtualHost>();
 
-    private NetworkMXBean networkBean;
-
     //
     // Constructors
     //
@@ -106,6 +104,11 @@
 
 	super(id, context, SERVICE, INSTANCE);
 
+	fsView = new RemoteFileSystemView(context);
+
+	networkBeanTracker = new MXBeanTracker<NetworkMXBean>(
+	    NetworkMXBean.class, context, NetworkUtil.OBJECT_NAME);
+
 	vHostNamePool = new PropertyGroupNamePool(getService(),
 	    VirtualHost.SMF_GROUP_PREFIX);
 
@@ -176,18 +179,14 @@
     }
 
     //
-    // ConnectionListener methods
+    // ManagedObject methods
     //
 
     @Override
-    protected void connectionChanged(ConnectionInfo info)
-	throws InstanceNotFoundException, IOException {
-	super.connectionChanged(info);
-
-	MBeanServerConnection mbsc = getMBeanServerConnection();
-	fsView = new RemoteFileSystemView(mbsc);
-
-	setNetworkBean(info);
+    public void dispose() {
+	super.dispose();
+	networkBeanTracker.dispose();
+	fsView.dispose();
     }
 
     //
@@ -395,20 +394,6 @@
     //
 
     public NetworkMXBean getNetworkMXBean() {
-        return networkBean;
-    }
-
-    private void setNetworkBean(ConnectionInfo info) throws IOException {
-	try {
-            networkBean = JMX.newMXBeanProxy(
-		info.getConnector().getMBeanServerConnection(),
-		NetworkUtil.OBJECT_NAME, NetworkMXBean.class);
-	} catch (IOException e) {
-            getLog().log(Level.SEVERE,
-		"Cannot locate " + NetworkUtil.OBJECT_NAME + " in MBeanServer",
-		e);
-
-            throw e;
-        }
+        return networkBeanTracker.getBean();
     }
 }
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MainControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MainControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -33,7 +33,7 @@
 import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.ManagedObject;
-import org.opensolaris.os.vp.panel.common.smf.ScfUtil;
+import org.opensolaris.os.vp.panel.common.smf.SmfUtil;
 import org.opensolaris.os.vp.panel.swing.control.*;
 import org.opensolaris.os.vp.panel.swing.view.ListSelectorPanel;
 import org.opensolaris.os.vp.util.misc.*;
@@ -122,7 +122,7 @@
 	    getPanelDescriptor().saveToRepo();
 
 	} catch (ScfException e) {
-	    ScfUtil.throwActionException(e);
+	    SmfUtil.throwActionException(e);
 	    throw new ActionFailedException(e);
 
 	} catch (SecurityException e) {
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeType.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/MimeType.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.apache.client.swing;
@@ -101,7 +100,7 @@
     }
 
     //
-    // SmfServiceInfo methods
+    // HasService methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/Module.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/Module.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.apache.client.swing;
@@ -97,7 +96,7 @@
     }
 
     //
-    // SmfServiceInfo methods
+    // HasService methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHost.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/apache/org/opensolaris/os/vp/panels/apache/client/swing/VirtualHost.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.apache.client.swing;
@@ -211,7 +210,7 @@
     }
 
     //
-    // SmfServiceInfo methods
+    // HasService methods
     //
 
     @Override
--- a/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -25,6 +25,7 @@
 
 package org.opensolaris.os.vp.panels.coreadm.client.swing;
 
+import java.beans.*;
 import java.io.IOException;
 import java.net.URL;
 import java.util.*;
@@ -32,10 +33,10 @@
 import javax.swing.Icon;
 import javax.swing.border.Border;
 import org.opensolaris.os.scf.common.ScfException;
-import org.opensolaris.os.vp.common.remotefile.*;
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
+import org.opensolaris.os.vp.panel.common.remotefile.*;
 import org.opensolaris.os.vp.panel.common.smf.*;
 import org.opensolaris.os.vp.panel.swing.control.*;
 import org.opensolaris.os.vp.panel.swing.smf.ServiceSwingPanelDescriptor;
@@ -75,7 +76,15 @@
     private DefaultControl control;
     private CoreConfig coreConfig_ = new CoreConfig();
     private CoreAdmSettingsTab settingsTab_;
-    private FileBrowserMXBean files_;
+    private MXBeanTracker<FileBrowserMXBean> filesBeanTracker;
+
+    private PropertyChangeListener filesBeanListener =
+	new PropertyChangeListener() {
+	    @Override
+	    public void propertyChange(PropertyChangeEvent event) {
+		updateCoreConfig();
+	    }
+	};
 
     //
     // Constructors
@@ -87,6 +96,13 @@
 
 	super(id, context, findSvc(context), INSTANCE);
 
+	filesBeanTracker = new MXBeanTracker<FileBrowserMXBean>(
+	    FileBrowserMXBean.class, context, FileBrowserUtil.OBJECT_NAME);
+
+        filesBeanTracker.addPropertyChangeListener(
+	    MXBeanTracker.PROPERTY_BEAN, filesBeanListener);
+	updateCoreConfig();
+
 	setComparator(SimpleHasId.COMPARATOR);
 
         DefaultControl tControl = new TabbedControl<CoreAdmPanelDescriptor>(
@@ -124,6 +140,15 @@
     // ManagedObject methods
     //
 
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	filesBeanTracker.dispose();
+	super.dispose();
+    }
+
     @Override
     public String getName() {
 	return Finder.getString("panel.coreadm.name");
@@ -153,27 +178,6 @@
 	settingsTab_.propertyChange(null);
     }
 
-    //
-    // ConnectionListener methods
-    //
-
-    @Override
-    protected void connectionChanged(ConnectionInfo info)
-	throws InstanceNotFoundException, IOException
-    {
-	super.connectionChanged(info);
-	files_ = JMX.newMXBeanProxy(getMBeanServerConnection(),
-	    FileBrowserUtil.OBJECT_NAME, FileBrowserMXBean.class);
-
-	/*
-	 * It is possible for us to be called from the superclass's
-	 * constructor; i.e. before we have initialized our instance
-	 * variables.
-	 */
-	if (coreConfig_ != null)
-	    refreshCores(new CoreConfig(), coreConfig_);
-    }
-
     /*
      * CoreAdmPanelDescriptor methods
      */
@@ -220,13 +224,14 @@
 	    if (!e.isRegex_) {
 		String name = stem + '/' + e.element_;
 		findCoresFile(cores, name, elements, index,
-		    files_.getFile(name));
+		    filesBeanTracker.getBean().getFile(name));
 	    } else {
 		/*
 		 * XXX: This doesn't handle %d and the fact it can
 		 * match nested directories.
 		 */
-		List<FileSnapshot> ff = files_.getFiles(stem);
+                List<FileSnapshot> ff =
+		    filesBeanTracker.getBean().getFiles(stem);
 		for (FileSnapshot f : ff) {
 		    String base = f.getBaseName();
 		    if (base.matches("^" + e.element_ + "$"))
--- a/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmSettingsTab.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CoreAdmSettingsTab.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.coreadm.client.swing;
@@ -33,7 +32,7 @@
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.control.*;
-import org.opensolaris.os.vp.panel.common.smf.ScfUtil;
+import org.opensolaris.os.vp.panel.common.smf.SmfUtil;
 import org.opensolaris.os.vp.panel.swing.control.*;
 import org.opensolaris.os.vp.util.misc.Finder;
 import org.opensolaris.os.vp.util.misc.property.MutableProperty;
@@ -101,7 +100,7 @@
 	try {
 	    value.write(descriptor.getService());
 	} catch (ScfException e) {
-	    ScfUtil.throwActionException(e);
+	    SmfUtil.throwActionException(e);
 	} catch (SecurityException e) {
 	    throw new ActionUnauthorizedException(e);
 	}
--- a/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CustomCoreSchemeEditControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/coreadm/org/opensolaris/os/vp/panels/coreadm/client/swing/CustomCoreSchemeEditControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.coreadm.client.swing;
@@ -29,7 +28,7 @@
 import java.net.URL;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.vp.panel.common.action.*;
-import org.opensolaris.os.vp.panel.common.smf.ScfUtil;
+import org.opensolaris.os.vp.panel.common.smf.SmfUtil;
 import org.opensolaris.os.vp.panel.swing.control.SwingSettingsControl;
 import org.opensolaris.os.vp.util.misc.Finder;
 import org.opensolaris.os.vp.util.misc.property.MutableProperty;
@@ -81,7 +80,7 @@
 	try {
 	    value.write(descriptor.getService());
 	} catch (ScfException e) {
-	    ScfUtil.throwActionException(e);
+	    SmfUtil.throwActionException(e);
 	} catch (SecurityException e) {
 	    throw new ActionUnauthorizedException(e);
 	}
--- a/usr/src/java/vpanels/panels/examples/org/opensolaris/os/vp/panels/example/time2/client/swing/TimePanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/examples/org/opensolaris/os/vp/panels/example/time2/client/swing/TimePanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,14 +20,11 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.example.time2.client.swing;
 
-import java.io.IOException;
-import javax.management.JMX;
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
@@ -37,15 +34,14 @@
 import org.opensolaris.os.vp.util.misc.Finder;
 
 public class TimePanelDescriptor
-    extends AbstractSwingPanelDescriptor<ManagedObject>
-    implements ConnectionListener {
+    extends AbstractSwingPanelDescriptor<ManagedObject> {
 
     //
     // Instance data
     //
 
     private DefaultControl control;
-    private TimeMXBean bean;
+    private MXBeanTracker<TimeMXBean> beanTracker;
 
     //
     // Constructors
@@ -68,29 +64,23 @@
 	control = new PanelFrameControl<TimePanelDescriptor>(this);
 	control.addChildren(new TimeControl(this));
 
-	setBean(context.getConnectionInfo());
-	context.addConnectionListener(this);
-    }
-
-    //
-    // ConnectionListener methods
-    //
-
-    @Override
-    public void connectionChanged(ConnectionEvent event) {
-	setBean(event.getConnectionInfo());
-    }
-
-    @Override
-    public void connectionFailed(ConnectionEvent event) {
-        // There's nothing particularly helpful we can do here except wait for
-        // the repaired connection in connectionChanged
+	beanTracker = new MXBeanTracker<TimeMXBean>(
+	    TimeMXBean.class, context, TimeUtil.OBJECT_NAME);
     }
 
     //
     // ManagedObject methods
     //
 
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	beanTracker.dispose();
+	super.dispose();
+    }
+
     @Override
     public String getName() {
 	return Finder.getString("panel.time.name");
@@ -110,20 +100,6 @@
     //
 
     public TimeMXBean getTimeBean() {
-	return bean;
-    }
-
-    //
-    // Private methods
-    //
-
-    private void setBean(ConnectionInfo info) {
-	try {
-	    bean = JMX.newMXBeanProxy(
-		info.getConnector().getMBeanServerConnection(),
-		TimeUtil.OBJECT_NAME, TimeMXBean.class);
-	} catch (IOException e) {
-	    bean = null;
-	}
+	return beanTracker.getBean();
     }
 }
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/EnableServiceAction.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/EnableServiceAction.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.firewall.client.swing;
@@ -59,7 +58,7 @@
 //	    try {
 		service.setEnabled(enable);
 //	    } catch (ScfException e) {
-//		ScfUtil.throwActionException(e);
+//		SmfUtil.throwActionException(e);
 //	    } catch (SecurityException e) {
 //		throw new ActionUnauthorizedException(e);
 //	    }
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/FirewallPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -29,7 +29,6 @@
 import java.io.IOException;
 import java.net.UnknownHostException;
 import java.util.*;
-import java.util.logging.Level;
 import javax.management.*;
 import javax.management.remote.JMXConnector;
 import javax.swing.*;
@@ -37,15 +36,14 @@
 import org.opensolaris.os.rad.ObjectException;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.smf.*;
-import org.opensolaris.os.vp.common.remotefile.RemoteFileSystemView;
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
 import org.opensolaris.os.vp.panel.common.network.*;
+import org.opensolaris.os.vp.panel.common.remotefile.RemoteFileSystemView;
 import org.opensolaris.os.vp.panel.common.smf.*;
 import org.opensolaris.os.vp.panel.swing.control.PanelFrameControl;
 import org.opensolaris.os.vp.panel.swing.smf.ServiceSwingPanelDescriptor;
-import org.opensolaris.os.vp.panels.firewall.client.swing.AccessPolicy.Type;
 import org.opensolaris.os.vp.util.misc.*;
 
 @SuppressWarnings({"serial"})
@@ -76,11 +74,13 @@
     // Instance data
     //
 
-    public AccessPolicy policy = new SimpleAccessPolicy(Type.NONE);
-    public AccessPolicy ovrPolicy = new SimpleAccessPolicy(Type.NONE);
+    public AccessPolicy policy = new SimpleAccessPolicy(AccessPolicy.Type.NONE);
+    public AccessPolicy ovrPolicy = new SimpleAccessPolicy(
+	AccessPolicy.Type.NONE);
+
     private DefaultControl control;
-    private FileSystemView fsView;
-    private NetworkMXBean networkBean;
+    private RemoteFileSystemView fsView;
+    private MXBeanTracker<NetworkMXBean> networkBeanTracker;
     private SimpleHasId tmpHasId = new SimpleHasId();
 
     private SimpleSmfPropertyGroupInfo defaultPgInfo;
@@ -100,6 +100,12 @@
 	ScfException, InvalidScfDataException, MissingScfDataException {
 
 	super(id, context, SERVICE, INSTANCE);
+
+	fsView = new RemoteFileSystemView(context);
+
+	networkBeanTracker = new MXBeanTracker<NetworkMXBean>(
+	    NetworkMXBean.class, context, NetworkUtil.OBJECT_NAME);
+
 	setComparator(SimpleHasId.COMPARATOR);
 
 	defaultPgInfo = new SimpleSmfPropertyGroupInfo(
@@ -142,10 +148,19 @@
     }
 
     //
-    //
-    //
     // ManagedObject methods
     //
+
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	networkBeanTracker.dispose();
+	fsView.dispose();
+	super.dispose();
+    }
+
     @Override
     public String getName() {
 	return Finder.getString("panel.firewall.name");
@@ -184,17 +199,6 @@
     //
 
     @Override
-    protected void connectionChanged(ConnectionInfo info)
-	throws InstanceNotFoundException, IOException {
-	super.connectionChanged(info);
-
-	MBeanServerConnection mbsc = getMBeanServerConnection();
-	fsView = new RemoteFileSystemView(mbsc);
-
-	setNetworkBean(info);
-    }
-
-    @Override
     public void refresh(boolean force) throws ScfException,
 	InvalidScfDataException, MissingScfDataException {
 	super.refresh(force);
@@ -305,7 +309,7 @@
     }
 
     public NetworkMXBean getNetworkMXBean() {
-	return networkBean;
+	return networkBeanTracker.getBean();
     }
 
     //
@@ -362,18 +366,4 @@
 
 	Collections.sort(services, SimpleHasId.COMPARATOR);
     }
-
-    private void setNetworkBean(ConnectionInfo info) throws IOException {
-	try {
-	    networkBean = JMX.newMXBeanProxy(
-	    info.getConnector().getMBeanServerConnection(),
-		NetworkUtil.OBJECT_NAME, NetworkMXBean.class);
-	} catch (IOException e) {
-	    getLog().log(Level.SEVERE,
-		Finder.getString("error.jmx.mxbean.missing",
-		NetworkUtil.OBJECT_NAME), e);
-
-	    throw e;
-	}
-    }
 }
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/GlobalControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/GlobalControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -27,12 +27,11 @@
 
 import java.net.UnknownHostException;
 import java.util.Map;
-import java.util.logging.*;
+import java.util.logging.Level;
 import org.opensolaris.os.scf.common.ScfException;
-import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.control.*;
-import org.opensolaris.os.vp.panel.common.smf.ScfUtil;
+import org.opensolaris.os.vp.panel.common.smf.SmfUtil;
 import org.opensolaris.os.vp.panel.swing.control.*;
 import org.opensolaris.os.vp.util.misc.*;
 
@@ -100,7 +99,7 @@
 	try {
 	    getPanelDescriptor().saveToRepo();
 	} catch (ScfException e) {
-	    ScfUtil.throwActionException(e);
+	    SmfUtil.throwActionException(e);
 	} catch (UnknownHostException e) {
 	    getLog().log(Level.SEVERE, e.getMessage());
 	    throw new ActionFailedException(e);
--- a/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/ServiceEditControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/firewall/org/opensolaris/os/vp/panels/firewall/client/swing/ServiceEditControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -27,7 +27,7 @@
 
 import java.net.*;
 import java.util.*;
-import java.util.logging.*;
+import java.util.logging.Level;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.control.*;
@@ -152,7 +152,7 @@
 	    throw new ActionFailedException(e);
 
 	} catch (ScfException e) {
-	    ScfUtil.throwActionException(e);
+	    SmfUtil.throwActionException(e);
 
 	} catch (SecurityException e) {
 	    throw new ActionUnauthorizedException(e);
--- a/usr/src/java/vpanels/panels/hypervisor/org/opensolaris/os/vp/panels/hypervisor/client/swing/HypervisorPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/hypervisor/org/opensolaris/os/vp/panels/hypervisor/client/swing/HypervisorPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -28,7 +28,7 @@
 import java.io.IOException;
 import java.util.List;
 import java.util.logging.*;
-import javax.management.*;
+import javax.management.InstanceNotFoundException;
 import javax.swing.*;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.vp.panel.common.*;
@@ -52,13 +52,13 @@
     public static final String PROPERTY_HYP = "enabled"; // Don't change
 
     protected static final List<ImageIcon> icons = IconFinder.getIcons(
-        new String[] {
-            "images/hypervisor-disabled-16.png",
-            "images/hypervisor-enabled-16.png",
-            "images/hypervisor-disabled-24.png",
-            "images/hypervisor-enabled-24.png",
-            "images/hypervisor-disabled-32.png",
-            "images/hypervisor-enabled-32.png"});
+	new String[] {
+	    "images/hypervisor-disabled-16.png",
+	    "images/hypervisor-enabled-16.png",
+	    "images/hypervisor-disabled-24.png",
+	    "images/hypervisor-enabled-24.png",
+	    "images/hypervisor-disabled-32.png",
+	    "images/hypervisor-enabled-32.png"});
 
     public static final String SMF_GROUP = "hypervisor";
 
@@ -66,20 +66,20 @@
     private static final String INSTANCE = "default";
 
     public BasicSmfMutableProperty<Integer> dom0Property =
-        new IntegerSmfProperty(PROPERTY_DOM0, this);
+	new IntegerSmfProperty(PROPERTY_DOM0, this);
     public BasicSmfMutableProperty<Integer> vcpuProperty =
-        new IntegerSmfProperty(PROPERTY_VCPUS, this);
+	new IntegerSmfProperty(PROPERTY_VCPUS, this);
     public BasicSmfMutableProperty<Boolean> pinProperty =
-        new BooleanSmfProperty(PROPERTY_PIN, this);
+	new BooleanSmfProperty(PROPERTY_PIN, this);
     public BasicSmfMutableProperty<Boolean> watProperty =
-        new BooleanSmfProperty(PROPERTY_WAT, this);
+	new BooleanSmfProperty(PROPERTY_WAT, this);
 
     //
     // Instance data
     //
 
     private DefaultControl control;
-    private HypervisorMXBean bean;
+    private MXBeanTracker<HypervisorMXBean> beanTracker;
 
     //
     // Constructors
@@ -96,79 +96,79 @@
      *		    a handle to interact with the Visual Panels client
      */
     public HypervisorPanelDescriptor(String id, ClientContext context)
-        throws IOException, InstanceNotFoundException,
-        ScfException, InvalidScfDataException, MissingScfDataException {
+	throws IOException, InstanceNotFoundException,
+	ScfException, InvalidScfDataException, MissingScfDataException {
 
-        super(id, context, SERVICE, INSTANCE);
+	super(id, context, SERVICE, INSTANCE);
+
+	beanTracker = new MXBeanTracker<HypervisorMXBean>(
+	    HypervisorMXBean.class, context, HypervisorUtil.OBJECT_NAME);
 
-        refresh(true);
+	refresh(true);
 
-        // Initialise Properties
-        if (dom0Property.getExistsInRepo())
-            dom0Property.updateFromRepo(true);
-        else
-            dom0Property.setFirstValue(2048);
+	// Initialise Properties
+	if (dom0Property.getExistsInRepo())
+	    dom0Property.updateFromRepo(true);
+	else
+	    dom0Property.setFirstValue(2048);
 
-        if (vcpuProperty.getExistsInRepo())
-            vcpuProperty.updateFromRepo(true);
-        else
-            vcpuProperty.setFirstValue(0);
+	if (vcpuProperty.getExistsInRepo())
+	    vcpuProperty.updateFromRepo(true);
+	else
+	    vcpuProperty.setFirstValue(0);
 
-        if (pinProperty.getExistsInRepo())
-            pinProperty.updateFromRepo(true);
-        else
-            pinProperty.setFirstValue(false);
+	if (pinProperty.getExistsInRepo())
+	    pinProperty.updateFromRepo(true);
+	else
+	    pinProperty.setFirstValue(false);
 
-        if (watProperty.getExistsInRepo())
-            watProperty.updateFromRepo(true);
-        else
-            watProperty.setFirstValue(false);
+	if (watProperty.getExistsInRepo())
+	    watProperty.updateFromRepo(true);
+	else
+	    watProperty.setFirstValue(false);
 
-        addProperties(getEnabledProperty());
-        addProperties(dom0Property);
-        addProperties(vcpuProperty);
-        addProperties(pinProperty);
-        addProperties(watProperty);
+	addProperties(getEnabledProperty());
+	addProperties(dom0Property);
+	addProperties(vcpuProperty);
+	addProperties(pinProperty);
+	addProperties(watProperty);
 
 	control = new PanelFrameControl<HypervisorPanelDescriptor>(this);
 	control.addChildren(new HypervisorControl(this));
 
-        setBean(context.getConnectionInfo());
-        context.addConnectionListener(this);
+	// Calculate an appropriate default value for dom0 reservation. This
+	// logic is also present in the svc-milestone method and changes
+	// to the calculation of this value here must be replicated there
+	// to keep the behaviour consistent.
 
-        // Calculate an appropriate default value for dom0 reservation. This
-        // logic is also present in the svc-milestone method and changes
-        // to the calculation of this value here must be replicated there
-        // to keep the behaviour consistent.
-
-        if (dom0Property.getFirstValue() == 0) {
-                int max = getPlatformMemory();
-                int val = (max / 2 < 2048) ? max /2 : 2048;
-                dom0Property.setFirstValue(val);
+	if (dom0Property.getFirstValue() == 0) {
+		int max = getPlatformMemory();
+		int val = (max / 2 < 2048) ? max /2 : 2048;
+		dom0Property.setFirstValue(val);
 		try {
 		    saveToRepo();
 		} catch (Exception e) {
 		    System.err.println("ERROR NUMBER 5628139.2");
 		}
-        }
-    }
-
-    //
-    // ConnectionListener methods
-    //
-
-    @Override
-    public void connectionChanged(ConnectionEvent event) {
-        setBean(event.getConnectionInfo());
+	}
     }
 
     //
     // ManagedObject methods
     //
 
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	beanTracker.dispose();
+	super.dispose();
+    }
+
     @Override
     public String getName() {
-        return Finder.getString("panel.hypervisor.name");
+	return Finder.getString("panel.hypervisor.name");
     }
 
     //
@@ -177,7 +177,7 @@
 
     @Override
     public List<? extends Icon> getIcons() {
-        return icons;
+	return icons;
     }
 
     //
@@ -186,7 +186,7 @@
 
     @Override
     public String getPropertyGroupName() {
-        return SMF_GROUP;
+	return SMF_GROUP;
     }
 
     //
@@ -195,8 +195,8 @@
 
     @Override
     public String getPropertyName() {
-        // Use the default property names
-        return null;
+	// Use the default property names
+	return null;
     }
 
     //
@@ -205,7 +205,7 @@
 
     @Override
     public Control getControl() {
-        return control;
+	return control;
     }
 
     //
@@ -213,86 +213,70 @@
     //
 
     public HypervisorMXBean getHypervisorBean() {
-        return bean;
+	return beanTracker.getBean();
     }
 
     public int getPlatformMemory() {
-        return (bean.getPlatformMemory());
+	return (getHypervisorBean().getPlatformMemory());
     }
 
     public int getPlatformCPUs() {
-        return (bean.getPlatformCPUs());
+	return (getHypervisorBean().getPlatformCPUs());
     }
 
     static void saveToRepo(HypervisorPanelDescriptor desc,
-        Runnable runnable) {
+	Runnable runnable) {
 
 	AggregatedRefreshService service = desc.getService();
 
-        synchronized (service) {
-            boolean needLock = !service.isPaused();
-            if (needLock) {
-                service.pause();
-            }
-            boolean success = false;
-            try {
-                runnable.run();
-                success = true;
-            } finally {
-                if (needLock) {
-                    if (success) {
-                        // Throws ScfException
-                        try {
-                            service.unpause();
-                        } catch (ScfException scfe) {
+	synchronized (service) {
+	    boolean needLock = !service.isPaused();
+	    if (needLock) {
+		service.pause();
+	    }
+	    boolean success = false;
+	    try {
+		runnable.run();
+		success = true;
+	    } finally {
+		if (needLock) {
+		    if (success) {
+			// Throws ScfException
+			try {
+			    service.unpause();
+			} catch (ScfException scfe) {
 			    Logger.getLogger(HypervisorPanelDescriptor.class.
 				getPackage().getName()).log(Level.SEVERE,
 				    "SCF exception: " + scfe.toString());
-                        }
-                    } else {
-                        // Unlock, refresh if needed, ignore any exceptions
-                        // since we are already in the midst of throwing one
-                        try {
-                           service.unpause();
-                        } catch (Throwable ignore) {
-                        }
-                    }
-                }
-            }
-        }
+			}
+		    } else {
+			// Unlock, refresh if needed, ignore any exceptions
+			// since we are already in the midst of throwing one
+			try {
+			   service.unpause();
+			} catch (Throwable ignore) {
+			}
+		    }
+		}
+	    }
+	}
     }
 
     void saveToRepo() {
-        HypervisorPanelDescriptor.saveToRepo(this, new Runnable() {
-            @Override
-            public void run() {
-                 for (MutableProperty<?> property : getProperties()) {
-                    if (property.isChanged()) {
-                        try {
-                            ((SmfMutableProperty)property).saveToRepo();
-                        } catch (ScfException scfe) {
+	HypervisorPanelDescriptor.saveToRepo(this, new Runnable() {
+	    @Override
+	    public void run() {
+		 for (MutableProperty<?> property : getProperties()) {
+		    if (property.isChanged()) {
+			try {
+			    ((SmfMutableProperty)property).saveToRepo();
+			} catch (ScfException scfe) {
 			    getLog().log(Level.SEVERE, "SCF exception: "
-                                    + scfe.toString());
-                        }
-                    }
-                }
-            }
-        });
+				    + scfe.toString());
+			}
+		    }
+		}
+	    }
+	});
     }
-
-    //
-    // Private methods
-    //
-
-    private void setBean(ConnectionInfo info) {
-        try {
-            bean = JMX.newMXBeanProxy(
-                info.getConnector().getMBeanServerConnection(),
-                HypervisorUtil.OBJECT_NAME, HypervisorMXBean.class);
-        } catch (IOException e) {
-            bean = null;
-        }
-    }
-
-
 }
--- a/usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/common/SharemgrEventMonitor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/common/SharemgrEventMonitor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -40,7 +40,6 @@
 import org.opensolaris.os.vp.panels.sharemgr.rad.ShareChange;
 import org.opensolaris.os.vp.panels.sharemgr.rad.ShareId;
 
-@SuppressWarnings({"serial"})
 public class SharemgrEventMonitor implements NotificationListener, Runnable {
     //
     // Static data
@@ -60,7 +59,6 @@
     private BlockingQueue<SharemgrNotification> notifications =
 	new LinkedBlockingQueue<SharemgrNotification>();
 
-    private MBeanServerConnection mbsc;
     private Thread thread;
 
     //
@@ -221,39 +219,21 @@
 	}
     }
 
-    public void restart() throws InstanceNotFoundException, IOException {
-	if (thread != null) {
-	    stop();
-	    while (true) {
-		try {
-		    thread.join();
-		    break;
-		} catch (InterruptedException ignore) {
-		}
-	    }
-	}
-	start();
-    }
-
     public void start() throws InstanceNotFoundException, IOException {
-	mbsc = descriptor.getMBeanServerConnection();
-	mbsc.addNotificationListener(SharemgrUtil.OBJECT_NAME, this,
-	    SharemgrUtil.NOTIFICATION_FILTER, null);
+	descriptor.getSharesBeanTracker().addNotificationListener(
+	    this, SharemgrUtil.NOTIFICATION_FILTER, null);
 
 	thread = new Thread(this);
 	thread.start();
     }
 
     public void stop() {
-	if (mbsc != null) {
-	    try {
-		mbsc.removeNotificationListener(SharemgrUtil.OBJECT_NAME, this);
+	try {
+	    descriptor.getSharesBeanTracker().removeNotificationListener(this);
 
-	    // If something prevented us from removing ourselves as a
-	    // notification listener, it probably doesn't matter anymore.
-	    } catch (Throwable ignore) {
-	    }
-	    mbsc = null;
+        // If something prevented us from removing ourselves as a notification
+        // listener, it probably doesn't matter anymore.
+	} catch (Throwable ignore) {
 	}
 
 	add(STOP);
--- a/usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/common/SharemgrPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/sharemgr/org/opensolaris/os/vp/panels/sharemgr/client/common/SharemgrPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,26 +20,26 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.sharemgr.client.common;
 
+import java.beans.*;
 import java.io.IOException;
 import java.util.*;
-import javax.management.*;
+import javax.management.InstanceNotFoundException;
 import javax.swing.filechooser.FileSystemView;
 import org.opensolaris.os.scf.common.ScfException;
-import org.opensolaris.os.vp.common.remotefile.RemoteFileSystemView;
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.model.ManagedObject;
+import org.opensolaris.os.vp.panel.common.remotefile.RemoteFileSystemView;
 import org.opensolaris.os.vp.panel.common.smf.*;
 import org.opensolaris.os.vp.panels.sharemgr.common.*;
-import org.opensolaris.os.vp.panels.sharemgr.rad.GroupId;
-import org.opensolaris.os.vp.panels.sharemgr.rad.GroupIdImpl;
-import org.opensolaris.os.vp.panels.sharemgr.rad.ShareErrorType;
-import org.opensolaris.os.vp.panels.sharemgr.rad.SharesMXBean;
+import org.opensolaris.os.vp.panels.sharemgr.common.Group;
+import org.opensolaris.os.vp.panels.sharemgr.common.Protocol;
+import org.opensolaris.os.vp.panels.sharemgr.common.SeqGroup;
+import org.opensolaris.os.vp.panels.sharemgr.rad.*;
 import org.opensolaris.os.vp.util.misc.*;
 
 @SuppressWarnings({"serial"})
@@ -97,7 +97,7 @@
     // Instance data
     //
 
-    private FileSystemView fsView;
+    private RemoteFileSystemView fsView;
 
     private SharemgrMXBean sharemgr;
     private SharemgrEventMonitor monitor;
@@ -107,6 +107,15 @@
     private SimpleHasGroupId tmpHasGroupId =
 	new SimpleHasGroupId(tmpGroupId);
 
+    private MXBeanTracker<SharesMXBean> sharesBeanTracker;
+    private PropertyChangeListener sharesBeanListener =
+	new PropertyChangeListener() {
+	    @Override
+	    public void propertyChange(PropertyChangeEvent event) {
+		sharesBeanChanged();
+	    }
+	};
+
     //
     // Constructors
     //
@@ -118,6 +127,15 @@
 
 	super(id, context, SERVICE, INSTANCE);
 
+	fsView = new RemoteFileSystemView(context);
+
+	sharesBeanTracker = new MXBeanTracker<SharesMXBean>(
+	    SharesMXBean.class, context, SharemgrUtil.OBJECT_NAME);
+
+	sharesBeanTracker.addPropertyChangeListener(
+	    MXBeanTracker.PROPERTY_BEAN, sharesBeanListener);
+	sharesBeanChanged();
+
 	protocols = new ArrayList<Protocol>(sharemgr.getProtocols());
 	Collections.sort(protocols);
 
@@ -133,38 +151,16 @@
     //
 
     @Override
-    public String getName() {
-	return Finder.getString("panel.sharemgr.name");
-    }
-
-    //
-    // PanelDescriptor methods
-    //
-
-    @Override
     public void dispose() {
 	monitor.stop();
+	sharesBeanTracker.dispose();
+	fsView.dispose();
 	super.dispose();
     }
 
-    //
-    // ConnectionListener methods
-    //
-
     @Override
-    protected void connectionChanged(ConnectionInfo info)
-	throws InstanceNotFoundException, IOException {
-	super.connectionChanged(info);
-
-	if (monitor != null) {
-	    monitor.restart();
-	}
-
-	MBeanServerConnection mbsc = getMBeanServerConnection();
-	fsView = new RemoteFileSystemView(mbsc);
-
-	sharemgr = new SharesMXBeanAdaptor(JMX.newMXBeanProxy(
-	    mbsc, SharemgrUtil.OBJECT_NAME, SharesMXBean.class));
+    public String getName() {
+	return Finder.getString("panel.sharemgr.name");
     }
 
     //
@@ -245,6 +241,10 @@
 	return sharemgr;
     }
 
+    public MXBeanTracker<SharesMXBean> getSharesBeanTracker() {
+	return sharesBeanTracker;
+    }
+
     public void refreshSharemgr() throws ScfException,
 	InvalidScfDataException, MissingScfDataException, SharemgrException {
 
@@ -306,4 +306,8 @@
 	    }
 	}
     }
+
+    private void sharesBeanChanged() {
+	sharemgr = new SharesMXBeanAdaptor(sharesBeanTracker.getBean());
+    }
 }
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/GeneralControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/GeneralControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -25,15 +25,11 @@
 
 package org.opensolaris.os.vp.panels.smf.client.swing;
 
-import java.util.Map;
-import org.opensolaris.os.vp.panel.common.control.*;
-import org.opensolaris.os.vp.panel.common.smf.SmfManagedObject;
+import org.opensolaris.os.vp.panel.common.smf.HasServiceTracker;
 import org.opensolaris.os.vp.panel.swing.smf.ServiceStatusControl;
 import org.opensolaris.os.vp.util.misc.Finder;
 
-public class GeneralControl<S extends SmfManagedObject>
-    extends ServiceStatusControl<SmfPanelDescriptor> {
-
+public class GeneralControl extends ServiceStatusControl<SmfPanelDescriptor> {
     //
     // Static data
     //
@@ -42,38 +38,13 @@
 	"smf.object.tab.general");
 
     //
-    // Instance data
-    //
-
-    private HasSmfManagedObject<S> parent;
-
-    //
     // Constructors
     //
 
     public GeneralControl(SmfPanelDescriptor descriptor,
-	HasSmfManagedObject<S> parent) {
-	super(descriptor);
-
-	setName(NAME);
-	this.parent = parent;
-    }
-
-    //
-    // Control methods
-    //
+	HasServiceTracker hasTracker) {
 
-    @Override
-    public void start(Navigator navigator, Map<String, String> parameters)
-	throws NavigationAbortedException, InvalidParameterException {
-
-	setObjectName(parent.getSmfManagedObject().getObjectName());
-	super.start(navigator, parameters);
-    }
-
-    @Override
-    public void stop(boolean isCancel) throws NavigationAbortedException {
-	setObjectName(null);
-	super.stop(isCancel);
+	super(descriptor, hasTracker);
+	setName(NAME);
     }
 }
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/HasSmfManagedObject.java	Wed Jul 21 10:13:44 2010 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-
-/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
- */
-
-package org.opensolaris.os.vp.panels.smf.client.swing;
-
-import org.opensolaris.os.vp.panel.common.smf.SmfManagedObject;
-
-public interface HasSmfManagedObject<S extends SmfManagedObject> {
-    S getSmfManagedObject();
-}
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/InstanceTabbedControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/InstanceTabbedControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -32,7 +32,8 @@
 import org.opensolaris.os.vp.panel.swing.control.TabbedControl;
 
 public class InstanceTabbedControl extends TabbedControl<SmfPanelDescriptor>
-    implements HasSmfManagedObject<InstanceManagedObject> {
+    implements HasSmfManagedObject<InstanceManagedObject>, HasServiceTracker {
+
     //
     // Static data
     //
@@ -44,8 +45,9 @@
     // Instance data
     //
 
+    private MainControl parent;
+    private ServiceTracker tracker;
     private InstanceManagedObject instance;
-    private MainControl parent;
 
     //
     // Constructors
@@ -59,6 +61,15 @@
     }
 
     //
+    // HasServiceTracker methods
+    //
+
+    @Override
+    public ServiceTracker getServiceTracker() {
+	return tracker;
+    }
+
+    //
     // Control methods
     //
 
@@ -76,15 +87,17 @@
 	FMRI fmri = parent.getSmfManagedObject().getSMFFmri().toInstanceFMRI(
 	    param);
 
-	String fmristr = fmri.toString();
-	SmfManagedObject smo = getPanelDescriptor().getRepo().getSMO(fmristr);
+	SmfManagedObject smo = getPanelDescriptor().getRepo().getSMO(
+	    fmri.toString());
 	if (smo == null || !(smo instanceof InstanceManagedObject)) {
 	    throw new InvalidParameterException(getId(), PARAM_INSTANCE,
-		fmristr);
+		param);
 	}
 
-	this.instance = (InstanceManagedObject)smo;
-	setInstance(instance);
+        tracker = new ServiceTracker(getPanelDescriptor().getClientContext(),
+	    smo.getObjectName());
+
+	setInstance((InstanceManagedObject)smo);
 
 	super.start(navigator, parameters);
     }
@@ -93,6 +106,9 @@
     public void stop(boolean isCancel) throws NavigationAbortedException {
 	super.stop(isCancel);
 
+	tracker.dispose();
+	tracker = null;
+
 	// Remove reference so it can be garbage collected if deleted
 	setInstance(null);
     }
@@ -106,8 +122,7 @@
 	if (children.size() == 0) {
 	    SmfPanelDescriptor descriptor = getPanelDescriptor();
 
-            addChildren(new GeneralControl<InstanceManagedObject>(
-		descriptor, this));
+            addChildren(new GeneralControl(descriptor, this));
 	    addChildren(new DependenciesControl<InstanceManagedObject>(
 		descriptor, this));
 	}
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/MainControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/MainControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -42,7 +42,7 @@
 
 public class MainControl extends ListSelectorControl<SmfPanelDescriptor,
     ListSelectorPanel, SmfManagedObject>
-    implements HasSmfManagedObject<ServiceManagedObject> {
+    implements HasSmfManagedObject<ServiceManagedObject>, HasServiceTracker {
 
     //
     // Inner classes
@@ -94,6 +94,7 @@
 
     private InstanceStatistics stats = new InstanceStatistics();
     private ServiceManagedObject service;
+    private ServiceTracker tracker;
 
     private MainListModel model;
     private FilterManagedObject<InstanceManagedObject> fRepo;
@@ -108,6 +109,24 @@
     }
 
     //
+    // HasSmfManagedObject methods
+    //
+
+    @Override
+    public ServiceManagedObject getSmfManagedObject() {
+	return service;
+    }
+
+    //
+    // HasServiceTracker methods
+    //
+
+    @Override
+    public ServiceTracker getServiceTracker() {
+	return tracker;
+    }
+
+    //
     // Control methods
     //
 
@@ -132,13 +151,15 @@
 	    param, null, null, null);
 
 	RepoManagedObject repo = getPanelDescriptor().getRepo();
-	SmfManagedObject service = repo.getServiceSMO(fmri.toString());
-	if (service == null || !(service instanceof ServiceManagedObject)) {
+	SmfManagedObject smo = repo.getServiceSMO(fmri.toString());
+	if (smo == null || !(smo instanceof ServiceManagedObject)) {
 	    throw new InvalidParameterException(getId(), PARAM_SERVICE, param);
 	}
 
-	this.service = (ServiceManagedObject)service;
-	setName(service.getName());
+        tracker = new ServiceTracker(getPanelDescriptor().getClientContext(),
+	    smo.getObjectName());
+
+	setService((ServiceManagedObject)smo);
 
 	fRepo = new FilterManagedObject<InstanceManagedObject>(repo, pred);
 	stats.setManagedObject(fRepo);
@@ -148,9 +169,15 @@
 
     @Override
     public void stop(boolean isCancel) throws NavigationAbortedException {
+	super.stop(isCancel);
+
+	tracker.dispose();
+	tracker = null;
+
+	// Remove reference so it can be garbage collected if deleted
+	setService(null);
+
 	stats.setManagedObject(null);
-	this.service = null;
-	super.stop(isCancel);
     }
 
     //
@@ -258,19 +285,19 @@
     }
 
     //
-    // HasSmfManagedObject methods
-    //
-
-    @Override
-    public ServiceManagedObject getSmfManagedObject() {
-	return service;
-    }
-
-    //
     // MainControl methods
     //
 
     public InstanceStatistics getStats() {
 	return stats;
     }
+
+    //
+    // Private methods
+    //
+
+    private void setService(ServiceManagedObject service) {
+	this.service = service;
+	setName(service == null ? null : service.getName());
+    }
 }
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/ServiceTabbedControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/ServiceTabbedControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -63,8 +63,7 @@
 	if (children.size() == 0) {
 	    SmfPanelDescriptor descriptor = getPanelDescriptor();
 
-            addChildren(new GeneralControl<ServiceManagedObject>(
-		descriptor, parent));
+            addChildren(new GeneralControl(descriptor, parent));
 	    addChildren(new DependenciesControl<ServiceManagedObject>(
 		descriptor, parent));
 	}
--- a/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/SmfPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/smf/org/opensolaris/os/vp/panels/smf/client/swing/SmfPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -25,6 +25,8 @@
 
 package org.opensolaris.os.vp.panels.smf.client.swing;
 
+import java.io.IOException;
+import javax.management.InstanceNotFoundException;
 import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
@@ -51,7 +53,9 @@
     // Constructors
     //
 
-    public SmfPanelDescriptor(String id, ClientContext context) {
+    public SmfPanelDescriptor(String id, ClientContext context)
+	throws InstanceNotFoundException, IOException {
+
 	super(id, context);
 	setName(Finder.getString("smf.panel.name"));
 
@@ -80,6 +84,15 @@
     // ManagedObject methods
     //
 
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	repo.dispose();
+	super.dispose();
+    }
+
     @Override
     public ManagedObjectStatus getStatus() {
 	return svccontrol.getStats().getStatus();
--- a/usr/src/java/vpanels/panels/svcs/org/opensolaris/os/vp/panels/svcs/client/swing/SvcsPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/svcs/org/opensolaris/os/vp/panels/svcs/client/swing/SvcsPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -26,7 +26,9 @@
 package org.opensolaris.os.vp.panels.svcs.client.swing;
 
 import java.beans.PropertyChangeListener;
+import java.io.IOException;
 import java.util.*;
+import javax.management.InstanceNotFoundException;
 import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
@@ -53,7 +55,8 @@
 
     @SuppressWarnings({"unchecked"})
     public SvcsPanelDescriptor(String id, ClientContext context)
-    {
+	throws InstanceNotFoundException, IOException {
+
 	super(id, context);
 
 	repo_ = new RepoManagedObject("repo", context);
--- a/usr/src/java/vpanels/panels/sysid/org/opensolaris/os/vp/panels/sysid/client/swing/SysIdPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/sysid/org/opensolaris/os/vp/panels/sysid/client/swing/SysIdPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,31 +20,28 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.sysid.client.swing;
 
-import java.io.IOException;
 import java.util.List;
-import javax.management.*;
+import javax.management.ObjectName;
 import javax.swing.*;
 import org.opensolaris.os.vp.common.panel.MBeanUtil;
 import org.opensolaris.os.vp.panel.common.*;
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
-import org.opensolaris.os.vp.panel.common.time.TimeMXBean;
+import org.opensolaris.os.vp.panel.common.time.*;
 import org.opensolaris.os.vp.panel.swing.control.PanelFrameControl;
 import org.opensolaris.os.vp.panel.swing.model.AbstractSwingPanelDescriptor;
-import org.opensolaris.os.vp.panel.swing.timezone.HasTimeZoneMXBean;
 import org.opensolaris.os.vp.panels.sysid.common.*;
 import org.opensolaris.os.vp.util.misc.*;
 
 @SuppressWarnings({"serial"})
 public class SysIdPanelDescriptor
     extends AbstractSwingPanelDescriptor<ManagedObject>
-    implements ConnectionListener, HasTimeZoneMXBean {
+    implements HasTimeMXBean {
 
     //
     // Static data
@@ -63,8 +60,8 @@
     //
 
     private DefaultControl control;
-    private SysIdMXBean sysidbean;
-    private TimeMXBean tzbean;
+    private MXBeanTracker<SysIdMXBean> sysidBeanTracker;
+    private MXBeanTracker<TimeMXBean> timeBeanTracker;
     private boolean hasFullPrivs;
 
     //
@@ -74,32 +71,54 @@
     public SysIdPanelDescriptor(String id, ClientContext context) {
 	super(id, context);
 
-	setBean(context.getConnectionInfo());
-	context.addConnectionListener(this);
+	sysidBeanTracker = new MXBeanTracker<SysIdMXBean>(
+	    SysIdMXBean.class, context, SysIdUtil.OBJECT_NAME);
+
+	ObjectName tzName = MBeanUtil.makeObjectName(
+	    MBeanUtil.VP_PANEL_DOMAIN + ".time", "Time");
+	timeBeanTracker = new MXBeanTracker<TimeMXBean>(
+	    TimeMXBean.class, context, tzName);
+
+	// Assume they both require the same privileges
+	hasFullPrivs = sysidBeanTracker.getBean().isSufficientlyPrivileged();
 
 	control = new PanelFrameControl<SysIdPanelDescriptor>(this);
 	control.addChildren(new SysIdControl(this));
     }
 
     //
-    // ConnectionListener methods
+    // HasIcons methods
     //
 
     @Override
-    public void connectionChanged(ConnectionEvent event) {
-	setBean(event.getConnectionInfo());
+    public List<? extends Icon> getIcons() {
+	return icons;
     }
 
+    //
+    // HasTimeMXBean methods
+    //
+
     @Override
-    public void connectionFailed(ConnectionEvent event) {
-        // There's nothing particularly helpful we can do here except wait for
-        // the repaired connection in connectionChanged
+    public TimeMXBean getTimeMXBean() {
+	return timeBeanTracker.getBean();
     }
 
     //
     // ManagedObject methods
     //
 
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	sysidBeanTracker.dispose();
+	timeBeanTracker.dispose();
+
+	super.dispose();
+    }
+
     @Override
     public String getName() {
 	return Finder.getString("panel.sysid.name");
@@ -120,48 +139,10 @@
     }
 
     //
-    // HasIcons methods
-    //
-
-    @Override
-    public List<? extends Icon> getIcons() {
-	return icons;
-    }
-
-    //
-    // HasTimeZoneMXBean methods
-    //
-
-    public TimeMXBean getTimeZoneMXBean() {
-	return tzbean;
-    }
-
-    //
     // SysIdPanelDescriptor methods
     //
 
-    SysIdMXBean getSysIdBean() {
-	return sysidbean;
-    }
-
-    //
-    // Private methods
-    //
-
-    private void setBean(ConnectionInfo info) {
-	try {
-	    sysidbean = JMX.newMXBeanProxy(
-		info.getConnector().getMBeanServerConnection(),
-		SysIdUtil.OBJECT_NAME, SysIdMXBean.class);
-	    ObjectName tzname = MBeanUtil.makeObjectName(
-		MBeanUtil.VP_PANEL_DOMAIN + ".time", "Time");
-	    tzbean = JMX.newMXBeanProxy(
-		info.getConnector().getMBeanServerConnection(),
-		tzname, TimeMXBean.class);
-	    /* Assume they both require the same privileges */
-	    hasFullPrivs = sysidbean.isSufficientlyPrivileged();
-	} catch (IOException e) {
-	    sysidbean = null;
-	}
+    public SysIdMXBean getSysIdBean() {
+	return sysidBeanTracker.getBean();
     }
 }
--- a/usr/src/java/vpanels/panels/sysid/org/opensolaris/os/vp/panels/sysid/client/swing/TimeZoneControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/sysid/org/opensolaris/os/vp/panels/sysid/client/swing/TimeZoneControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.sysid.client.swing;
@@ -47,6 +46,6 @@
     public TimeZoneControl(SysIdPanelDescriptor descriptor) {
 
 	super(ID, NAME, descriptor, new TimeZoneModel(descriptor),
-	    new TimeZonePanel(descriptor.getTimeZoneMXBean(), null));
+	    new TimeZonePanel(descriptor.getTimeMXBean(), null));
     }
 }
--- a/usr/src/java/vpanels/panels/sysmon/org/opensolaris/os/vp/panels/sysmon/client/swing/SmfMonitoredResource.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/sysmon/org/opensolaris/os/vp/panels/sysmon/client/swing/SmfMonitoredResource.java	Wed Jul 21 20:26:39 2010 -0400
@@ -26,7 +26,9 @@
 package org.opensolaris.os.vp.panels.sysmon.client.swing;
 
 import java.beans.PropertyChangeListener;
+import java.io.IOException;
 import java.util.List;
+import javax.management.InstanceNotFoundException;
 import javax.swing.Icon;
 import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.control.*;
@@ -57,7 +59,9 @@
     // Constructors
     //
 
-    public SmfMonitoredResource(ClientContext context) {
+    public SmfMonitoredResource(ClientContext context)
+	throws InstanceNotFoundException, IOException {
+
 	this.context = context;
 	setName(NAME);
 
--- a/usr/src/java/vpanels/panels/sysmon/org/opensolaris/os/vp/panels/sysmon/client/swing/SysMonPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/sysmon/org/opensolaris/os/vp/panels/sysmon/client/swing/SysMonPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -26,7 +26,9 @@
 package org.opensolaris.os.vp.panels.sysmon.client.swing;
 
 import java.awt.Image;
+import java.io.IOException;
 import java.util.List;
+import javax.management.InstanceNotFoundException;
 import javax.swing.*;
 import org.opensolaris.os.vp.panel.common.ClientContext;
 import org.opensolaris.os.vp.panel.common.control.Control;
@@ -61,7 +63,9 @@
     // Constructors
     //
 
-    public SysMonPanelDescriptor(String id, ClientContext context) {
+    public SysMonPanelDescriptor(String id, ClientContext context)
+	throws InstanceNotFoundException, IOException {
+
 	super(id, context);
 
 	setName(Finder.getString("panel.name"));
--- a/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/MainControl.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/MainControl.java	Wed Jul 21 20:26:39 2010 -0400
@@ -170,7 +170,7 @@
 
 	    String zoneId;
 	    try {
-		zoneId = descriptor.getTimeBean().getDefaultTimeZone();
+		zoneId = descriptor.getTimeMXBean().getDefaultTimeZone();
 	    } catch (ObjectException e) {
 		zoneId = "UTC";
 	    }
--- a/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/NTPModel.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/NTPModel.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,27 +20,20 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.time.client.swing;
 
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
 import org.opensolaris.os.rad.ObjectException;
 import org.opensolaris.os.scf.common.ScfException;
 import org.opensolaris.os.smf.SmfState;
-import org.opensolaris.os.vp.panel.common.action.ActionFailedException;
-import org.opensolaris.os.vp.panel.common.action.ActionUnauthorizedException;
+import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.model.AbstractModel;
-import org.opensolaris.os.vp.panel.common.smf.ScfUtil;
-import org.opensolaris.os.vp.panel.common.smf.SmfEnabledProperty;
-import org.opensolaris.os.vp.panel.common.smf.ServiceMXBean;
-import org.opensolaris.os.vp.panel.common.time.ServerInfo;
-import org.opensolaris.os.vp.panel.common.time.TimeMXBean;
-import org.opensolaris.os.vp.util.misc.*;
+import org.opensolaris.os.vp.panel.common.smf.*;
+import org.opensolaris.os.vp.panel.common.time.*;
+import org.opensolaris.os.vp.util.misc.Finder;
 
 public class NTPModel extends AbstractModel<TimePanelDescriptor> {
 
@@ -70,7 +63,7 @@
 	// XXX generic NTPModel shouldn't assume a ServiceSwingPanelDescriptor
 	enabled_ = getSource().isEnabled();
 	try {
-	    servers_ = getSource().getTimeBean().getNTPServers();
+	    servers_ = getSource().getTimeMXBean().getNTPServers();
 	} catch (ObjectException e) {
 	    servers_ = Collections.emptyList();
 	}
@@ -90,7 +83,7 @@
 	validate();
 
 	TimePanelDescriptor descriptor = getSource();
-	TimeMXBean bean = descriptor.getTimeBean();
+	TimeMXBean bean = descriptor.getTimeMXBean();
 
 	try {
 	    bean.setNTPServers(servers_);
@@ -113,7 +106,7 @@
 	    throw new ActionUnauthorizedException(e);
 
 	} catch (ScfException e) {
-	    ScfUtil.throwActionException(e);
+	    SmfUtil.throwActionException(e);
 	    throw new ActionFailedException(Finder.getString(
 		"ntp.error.service." + (enabled_ ? "start" : "stop")), e);
 	}
--- a/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimeModel.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimeModel.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,17 +20,13 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.time.client.swing;
 
-import java.io.IOException;
 import org.opensolaris.os.rad.ObjectException;
-import org.opensolaris.os.vp.common.panel.auth.UnauthorizedException;
-import org.opensolaris.os.vp.panel.common.action.ActionFailedException;
-import org.opensolaris.os.vp.panel.common.action.ActionUnauthorizedException;
+import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.model.AbstractModel;
 import org.opensolaris.os.vp.panel.common.time.TimeMXBean;
 import org.opensolaris.os.vp.util.misc.Finder;
@@ -51,7 +47,7 @@
 
     public void load() {
 	try {
-	    offset_ = getSource().getTimeBean().getTime() -
+	    offset_ = getSource().getTimeMXBean().getTime() -
 		System.currentTimeMillis();
 	} catch (ObjectException e) {
 	    offset_ = 0;
@@ -61,7 +57,7 @@
     public void save() throws ActionFailedException,
 	ActionUnauthorizedException {
 
-	TimeMXBean bean = getSource().getTimeBean();
+	TimeMXBean bean = getSource().getTimeMXBean();
 
 	try {
 	    bean.setTime(System.currentTimeMillis() + offset_);
--- a/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimePanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimePanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,8 +20,7 @@
  */
 
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.time.client.swing;
@@ -37,16 +36,15 @@
 import org.opensolaris.os.vp.panel.common.control.*;
 import org.opensolaris.os.vp.panel.common.model.*;
 import org.opensolaris.os.vp.panel.common.smf.*;
-import org.opensolaris.os.vp.panel.common.time.TimeMXBean;
+import org.opensolaris.os.vp.panel.common.time.*;
 import org.opensolaris.os.vp.panel.swing.control.PanelFrameControl;
 import org.opensolaris.os.vp.panel.swing.smf.ServiceSwingPanelDescriptor;
-import org.opensolaris.os.vp.panel.swing.timezone.HasTimeZoneMXBean;
 import org.opensolaris.os.vp.util.misc.*;
 
 @SuppressWarnings({"serial"})
 public class TimePanelDescriptor
     extends ServiceSwingPanelDescriptor<ManagedObject>
-    implements HasTimeZoneMXBean {
+    implements HasTimeMXBean {
 
     //
     // Static data
@@ -68,7 +66,7 @@
     //
 
     private DefaultControl control;
-    private TimeMXBean timebean;
+    private MXBeanTracker<TimeMXBean> beanTracker;
     private boolean hasFullPrivs;
 
     //
@@ -81,7 +79,11 @@
 
 	super(id, context, SERVICE, INSTANCE);
 
-	setBean(context.getConnectionInfo());
+	ObjectName oName = MBeanUtil.makeVPObjectName("panels.time", "Time");
+	beanTracker = new MXBeanTracker<TimeMXBean>(
+	    TimeMXBean.class, context, oName);
+
+	hasFullPrivs = getTimeMXBean().isSufficientlyPrivileged();
 
 	refresh(true);
 	control = new PanelFrameControl<TimePanelDescriptor>(this);
@@ -89,16 +91,6 @@
     }
 
     //
-    // ConnectionListener methods
-    //
-
-    @Override
-    public void connectionChanged(ConnectionEvent event) {
-	super.connectionChanged(event);
-	setBean(event.getConnectionInfo());
-    }
-
-    //
     // HasIcons methods
     //
 
@@ -108,9 +100,27 @@
     }
 
     //
+    // HasTimeMXBean methods
+    //
+
+    @Override
+    public TimeMXBean getTimeMXBean() {
+	return beanTracker.getBean();
+    }
+
+    //
     // ManagedObject methods
     //
 
+    /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	beanTracker.dispose();
+	super.dispose();
+    }
+
     @Override
     public String getName() {
 	return Finder.getString("panel.time.name");
@@ -146,36 +156,4 @@
 	}
 	return Finder.getString(resource);
     }
-
-    //
-    // HasTimeZoneMXBean
-    //
-
-    public TimeMXBean getTimeZoneMXBean() {
-	return timebean;
-    }
-
-    //
-    // TimePanelDescriptor methods
-    //
-
-    protected TimeMXBean getTimeBean() {
-	return timebean;
-    }
-
-    //
-    // Private methods
-    //
-
-    private void setBean(ConnectionInfo info) {
-	try {
-	    timebean = JMX.newMXBeanProxy(
-		info.getConnector().getMBeanServerConnection(),
-		MBeanUtil.makeVPObjectName("panels.time", "Time"),
-		TimeMXBean.class);
-	    hasFullPrivs = timebean.isSufficientlyPrivileged();
-	} catch (IOException e) {
-	    timebean = null;
-	}
-    }
 }
--- a/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimeZoneObject.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/time/org/opensolaris/os/vp/panels/time/client/swing/TimeZoneObject.java	Wed Jul 21 20:26:39 2010 -0400
@@ -20,21 +20,17 @@
  */
 
 /*
- * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 package org.opensolaris.os.vp.panels.time.client.swing;
 
-import java.util.Date;
-import java.util.TimeZone;
+import java.util.*;
 import javax.swing.Icon;
-import org.opensolaris.os.vp.panel.common.action.ActionFailedException;
-import org.opensolaris.os.vp.panel.common.action.ActionUnauthorizedException;
+import org.opensolaris.os.vp.panel.common.action.*;
 import org.opensolaris.os.vp.panel.common.control.Control;
 import org.opensolaris.os.vp.panel.swing.model.SimpleModelControl;
-import org.opensolaris.os.vp.panel.swing.timezone.TimeZoneModel;
-import org.opensolaris.os.vp.panel.swing.timezone.TimeZonePanel;
+import org.opensolaris.os.vp.panel.swing.timezone.*;
 import org.opensolaris.os.vp.util.misc.Finder;
 import org.opensolaris.os.vp.util.swing.time.SimpleTimeModel;
 
@@ -68,7 +64,7 @@
 		onsave.run();
 	    }
 	};
-	panel_ = new TimeZonePanel(desc.getTimeBean(), updateModel);
+	panel_ = new TimeZonePanel(desc.getTimeMXBean(), updateModel);
         SimpleModelControl<?, TimePanelDescriptor, ?> control =
 	    SimpleModelControl.createControl(ID, NAME, desc, dataModel, panel_);
 	control.setHelpURL(
--- a/usr/src/java/vpanels/panels/usermgr/org/opensolaris/os/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java	Wed Jul 21 10:13:44 2010 -0700
+++ b/usr/src/java/vpanels/panels/usermgr/org/opensolaris/os/vp/panels/usermgr/client/swing/UserMgrPanelDescriptor.java	Wed Jul 21 20:26:39 2010 -0400
@@ -26,45 +26,24 @@
 package org.opensolaris.os.vp.panels.usermgr.client.swing;
 
 import java.awt.Image;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.logging.Level;
-import javax.management.JMX;
 import javax.management.ObjectName;
 import javax.swing.Icon;
 import org.opensolaris.os.rad.ObjectException;
 import org.opensolaris.os.vp.common.panel.MBeanUtil;
-import org.opensolaris.os.vp.panel.common.ClientContext;
-import org.opensolaris.os.vp.panel.common.ConnectionEvent;
-import org.opensolaris.os.vp.panel.common.ConnectionInfo;
-import org.opensolaris.os.vp.panel.common.ConnectionListener;
-import org.opensolaris.os.vp.panel.common.action.ActionAbortedException;
-import org.opensolaris.os.vp.panel.common.action.ActionFailedException;
-import org.opensolaris.os.vp.panel.common.action.ActionUnauthorizedException;
-import org.opensolaris.os.vp.panel.common.control.Control;
-import org.opensolaris.os.vp.panel.common.control.DefaultControl;
-import org.opensolaris.os.vp.panel.common.usermgr.Group;
-import org.opensolaris.os.vp.panel.common.usermgr.User;
-import org.opensolaris.os.vp.panel.common.usermgr.UserImpl;
-import org.opensolaris.os.vp.panel.common.usermgr.UserMgrError;
-import org.opensolaris.os.vp.panel.common.usermgr.UserMgrErrorType;
-import org.opensolaris.os.vp.panel.common.usermgr.UserMgrMXBean;
-import org.opensolaris.os.vp.panel.common.usermgr.UserType;
+import org.opensolaris.os.vp.panel.common.*;
+import org.opensolaris.os.vp.panel.common.action.*;
+import org.opensolaris.os.vp.panel.common.control.*;
+import org.opensolaris.os.vp.panel.common.model.PanelDescriptor;
+import org.opensolaris.os.vp.panel.common.usermgr.*;
 import org.opensolaris.os.vp.panel.swing.control.PanelFrameControl;
 import org.opensolaris.os.vp.panel.swing.model.AbstractSwingPanelDescriptor;
-import org.opensolaris.os.vp.util.misc.ChangeableAggregator;
-import org.opensolaris.os.vp.util.misc.Finder;
-import org.opensolaris.os.vp.util.misc.IconUtil;
-import org.opensolaris.os.vp.util.misc.SimpleHasId;
-import org.opensolaris.os.vp.util.misc.property.IntegerProperty;
-import org.opensolaris.os.vp.util.misc.property.MutableProperty;
+import org.opensolaris.os.vp.util.misc.*;
+import org.opensolaris.os.vp.util.misc.property.*;
 
 public class UserMgrPanelDescriptor
-    extends AbstractSwingPanelDescriptor<UserManagedObject>
-    implements ConnectionListener {
+    extends AbstractSwingPanelDescriptor<UserManagedObject> {
 
     //
     // Static data
@@ -81,7 +60,7 @@
     //
 
     private DefaultControl control;
-    private UserMgrMXBean bean;
+    private MXBeanTracker<UserMgrMXBean> beanTracker;
 
     private List<UserManagedObject> deleteList =
 	new ArrayList<UserManagedObject> ();
@@ -114,8 +93,8 @@
     public UserMgrPanelDescriptor(String id, ClientContext context) {
         super(id, context);
 
-        setBean(context.getConnectionInfo());
-        context.addConnectionListener(this);
+	beanTracker = new MXBeanTracker<UserMgrMXBean>(
+	    UserMgrMXBean.class, context, OBJECT_NAME);
 
 	setComparator(SimpleHasId.COMPARATOR);
 
@@ -132,21 +111,6 @@
     }
 
     //
-    // ConnectionListener methods
-    //
-
-    @Override
-    public void connectionChanged(ConnectionEvent event) {
-	// There is no graceful way to handle this failure
-	setBean(event.getConnectionInfo());
-    }
-
-    @Override
-    public void connectionFailed(ConnectionEvent event) {
-        // Nothing to do
-    }
-
-    //
     // PanelDescriptor methods
     //
 
@@ -195,10 +159,19 @@
     }
 
     //
-    // AbstractManagedObject methods
+    // ManagedObject methods
     //
 
     /**
+     * Stops monitoring the connection to the remote host.
+     */
+    @Override
+    public void dispose() {
+	beanTracker.dispose();
+	super.dispose();
+    }
+
+    /**
      * Returns the name of this Managed Object.
      */
     @Override
@@ -209,6 +182,7 @@
     //
     // AbstractManagedObject methods
     //
+
     @Override
     public void addChildren(UserManagedObject... toAdd) {
 	super.addChildren(toAdd);
@@ -234,7 +208,7 @@
     //
 
     public UserMgrMXBean getUserMgrBean() {
-        return bean;
+        return beanTracker.getBean();
     }
 
     public UserManagedObject getUserManagedObject(String id) {
@@ -272,7 +246,7 @@
 	while (it.hasNext()) {
 	    UserManagedObject umo = it.next();
 	    try {
-		bean.deleteUser(umo.getName());
+		getUserMgrBean().deleteUser(umo.getName());
 		it.remove();
 		deletedProperty.setValue(deletedProperty.getValue() - 1);
 	    } catch (SecurityException se) {
@@ -307,7 +281,8 @@
 	    UserManagedObject umo = it.next();
 	    try {
 		String password = new String(umo.getPassword());
-		User user = bean.addUser(umo.getNewUser(), password);
+		User user = getUserMgrBean().addUser(
+		    umo.getNewUser(), password);
 		password = null;  // for gc
 		it.remove();
 		addedProperty.setValue(addedProperty.getValue() - 1);
@@ -353,11 +328,11 @@
 			    password = new String(umo.getPassword());
 			else
 			    password = null;
-			bean.modifyUser(user, password);
+			getUserMgrBean().modifyUser(user, password);
 			password = null;
 		    }
 		    if (umo.getIsAdminProperty().isChanged()) {
-			bean.setAdministrator(umo.getUsername(),
+			getUserMgrBean().setAdministrator(umo.getUsername(),
 			    umo.isAdministrator());
 		    }
 		} catch (SecurityException se) {
@@ -396,7 +371,7 @@
 
     public List<Group> getGroups() {
 	try {
-	    return bean.getGroups();
+	    return getUserMgrBean().getGroups();
         } catch (ObjectException e) {
             getLog().log(Level.SEVERE, "Error getting group list.", e);
 	}
@@ -405,7 +380,7 @@
 
     public List<String> getShells() {
 	try {
-	    return bean.getShells();
+	    return getUserMgrBean().getShells();
         } catch (ObjectException e) {
             getLog().log(Level.SEVERE, "Error getting shell list.", e);
 	}
@@ -415,7 +390,7 @@
     public UserImpl getDefaultUser() throws ActionFailedException,
 	ActionUnauthorizedException {
 	try {
-	    User defUser = bean.getDefaultUser();
+	    User defUser = getUserMgrBean().getDefaultUser();
 	    return new UserImpl("", 0L, defUser.getGroupID(), "", "",
 		defUser.getDefaultShell());
 	} catch (SecurityException se) {
@@ -430,21 +405,10 @@
     // Private methods
     //
 
-    private void setBean(ConnectionInfo info) {
-        try {
-            bean = JMX.newMXBeanProxy(
-		info.getConnector().getMBeanServerConnection(),
-		OBJECT_NAME, UserMgrMXBean.class);
-        } catch (IOException ioe) {
-            bean = null;
-	    getLog().log(Level.SEVERE, "Error getting bean.", ioe);
-        }
-    }
-
     private List<User> getUsers() {
 	List<User> users = null;
 	try {
-	    users = bean.getUsers();
+	    users = getUserMgrBean().getUsers();
         } catch (ObjectException e) {
             getLog().log(Level.SEVERE, "Error getting user list.", e);
 	}
@@ -460,6 +424,7 @@
 	try {
 	    for (User user : users) {
 		String username = user.getUsername();
+		UserMgrMXBean bean = getUserMgrBean();
 		boolean isAdmin = bean.isAdministrator(username);
 		UserType uType = bean.getUserType(username);
 		UserManagedObject umo = new UserManagedObject(this,