/*******************************************************************************
 * Copyright (c) 2003, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.server.core.internal;

import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.server.core.*;
import org.eclipse.wst.server.core.model.InternalInitializer;
import org.eclipse.wst.server.core.model.PublishOperation;
import org.eclipse.wst.server.core.model.ServerBehaviourDelegate;
import org.eclipse.wst.server.core.model.ServerDelegate;
/**
 * 
 */
public class ServerWorkingCopy extends Server implements IServerWorkingCopy {
	protected Server server;
	protected WorkingCopyHelper wch;

	protected ServerDelegate workingCopyDelegate;

	// working copy
	public ServerWorkingCopy(Server server) {
		super(server.getFile());
		this.server = server;
		
		map = new HashMap<String, Object>(server.map);
		wch = new WorkingCopyHelper(this);
		
		resolve();
	}

	// creation
	public ServerWorkingCopy(String id, IFile file, IRuntime runtime, IServerType serverType) {
		super(id, file, runtime, serverType);
		wch = new WorkingCopyHelper(this);
		wch.setDirty(true);
		serverState = ((ServerType)serverType).getInitialState();
	}

	public boolean isWorkingCopy() {
		return true;
	}

	public IServer getOriginal() {
		return server;
	}

	public IServerWorkingCopy createWorkingCopy() {
		return this;
	}

	public int getServerState() {
		if (server != null)
			return server.getServerState();
		return super.getServerState();
	}

	public void setServerState(int state) {
		if (server != null)
			server.setServerState(state);
		else
			super.setServerState(state);
	}

	public int getServerPublishState() {
		if (server != null)
			return server.getServerPublishState();
		return super.getServerPublishState();
	}

	public void setServerPublishState(int state) {
		if (server != null)
			server.setServerPublishState(state);
		else
			super.setServerPublishState(state);
	}

	public IStatus getServerStatus() {
		if (server != null)
			return server.getServerStatus();
		return super.getServerStatus();
	}

	public void setServerStatus(IStatus status) {
		if (server != null)
			server.setServerStatus(status);
		else
			super.setServerStatus(status);
	}

	public int getModuleState(IModule[] module) {
		if (server != null)
			return server.getModuleState(module);
		return super.getModuleState(module);
	}

	public void setModuleState(IModule[] module, int state) {
		if (server != null)
			server.setModuleState(module, state);
		else
			super.setModuleState(module, state);
	}

	public int getModulePublishState(IModule[] module) {
		if (server != null)
			return server.getModulePublishState(module);
		return super.getModulePublishState(module);
	}

	public void setModulePublishState(IModule[] module, int state) {
		if (server != null)
			server.setModulePublishState(module, state);
		else
			super.setModulePublishState(module, state);
	}

	public boolean getModuleRestartState(IModule[] module) {
		if (server != null)
			return server.getModuleRestartState(module);
		return super.getModuleRestartState(module);
	}

	public void setModuleRestartState(IModule[] module, boolean r) {
		if (server != null)
			server.setModuleRestartState(module, r);
		else
			super.setModuleRestartState(module, r);
	}

	public IStatus getModuleStatus(IModule[] module) {
		if (server != null)
			return server.getModuleStatus(module);
		return super.getModuleStatus(module);
	}

	public void setModuleStatus(IModule[] module, IStatus status) {
		if (server != null)
			server.setModuleStatus(module, status);
		else
			super.setModuleStatus(module, status);
	}

	public String getMode() {
		if (server != null)
			return server.getMode();
		return mode;
	}

	public void setMode(String mode) {
		if (server != null)
			server.setMode(mode);
		else
			super.setMode(mode);
	}

	public void setAttribute(String attributeName, int value) {
		canModifyAttribute(attributeName);		
		wch.setAttribute(attributeName, value);
	}

	public void setAttribute(String attributeName, boolean value) {
		canModifyAttribute(attributeName);
		wch.setAttribute(attributeName, value);
	}

	public void setAttribute(String attributeName, String value) {
		canModifyAttribute(attributeName);
		wch.setAttribute(attributeName, value);
	}

	public void setAttribute(String attributeName, List<String> value) {
		canModifyAttribute(attributeName);
		wch.setAttribute(attributeName, value);
	}

	public void setAttribute(String attributeName, Map value) {
		canModifyAttribute(attributeName);
		wch.setAttribute(attributeName, value);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.server.core.IServerWorkingCopy#setName(java.lang.String)
	 */
	public void setName(String name) {
		setAttribute(PROP_NAME, name);
		boolean set = getAttribute(PROP_ID_SET, false);
		if (server == null && !set)
			setAttribute(PROP_ID, name);
	}

	public void setReadOnly(boolean b) {
		setAttribute(PROP_LOCKED, b);
	}

	/**
	 * Sets whether this element is private.
	 * Generally speaking, elements marked private are internal ones
	 * that should not be shown to users (because they won't know
	 * anything about them).
	 * 
	 * @param b <code>true</code> if this element is private,
	 * and <code>false</code> otherwise
	 * @see #isPrivate()
	 */
	public void setPrivate(boolean b) {
		setAttribute(PROP_PRIVATE, b);
	}

	public void setHost(String host) {
		setAttribute(PROP_HOSTNAME, host);
	}

	public void setAutoPublishTime(int p) {
		setAttribute(PROP_AUTO_PUBLISH_TIME, p);
	}

	public void setStartTimeout(int p) {
		setAttribute(PROP_START_TIMEOUT, p);
	}

	public void setStopTimeout(int p) {
		setAttribute(PROP_STOP_TIMEOUT, p);
	}

	public void setAutoPublishSetting(int s) {
		setAttribute(PROP_AUTO_PUBLISH_SETTING, s);
	}

	public void setServerConfiguration(IFolder config) {
		this.configuration = config;
		if (configuration == null)
			setAttribute(CONFIGURATION_ID, (String)null);
		else
			setAttribute(CONFIGURATION_ID, configuration.getFullPath().toString());
	}

	/**
	 * Disable the preferred publish operation.
	 * 
	 * @param op a publish operation
	 * @return true if change is made. 
	 */
	public boolean disablePreferredPublishOperations(PublishOperation op) {
		List<String> list = getAttribute(PROP_DISABLED_PERFERRED_TASKS, (List<String>)null);
		if (list == null)
			list = new ArrayList<String>();
		
		String opId = getPublishOperationId(op);
		if (list.contains(opId))
			return false;
		list.add(opId);
		setAttribute(PROP_DISABLED_PERFERRED_TASKS, list);
		return true;
	}

	/**
	 * Enable the optional publish operation. Optional publish operation is not ran by default.
	 * 
	 * @param op a publish operation
	 * @return true if change is made. 
	 */
	public boolean enableOptionalPublishOperations(PublishOperation op) {
		List<String> list = getAttribute(PROP_ENABLED_OPTIONAL_TASKS, (List<String>)null);
		if (list == null)
			list = new ArrayList<String>();
		
		String opId = getPublishOperationId(op);
		if (list.contains(opId))
			return false;
		list.add(opId);
		setAttribute(PROP_ENABLED_OPTIONAL_TASKS, list);
		return true;
	}

	/**
	 * Reset all preferred operations to default
	 */
	public void resetPreferredPublishOperations() {
		setAttribute(PROP_DISABLED_PERFERRED_TASKS, (List<String>)null);
	}

	/**
	 * Reset all optional operations to default
	 */
	public void resetOptionalPublishOperations() {
		setAttribute(PROP_ENABLED_OPTIONAL_TASKS, (List<String>)null);
	}

	public void setPublisherEnabled(Publisher pub, boolean enabled) {
		if (pub == null)
			return;
		
		// copy over all elements except the updated publisher
		List<String> list = getAttribute(PROP_PUBLISHERS, EMPTY_LIST);
		List<String> newList = new ArrayList<String>();
		Iterator<String> iter = list.iterator();
		while (iter.hasNext()) {
			String id = iter.next();
			int ind = id.indexOf(":");
			if (!pub.getId().equals(id.substring(0, ind)))
				newList.add(id);
		}
		
		String s = pub.getId() + ":";
		if (enabled)
			s += "true";
		else
			s += "false";
		newList.add(s);
		setAttribute(PROP_PUBLISHERS, newList);
	}

	/**
	 * Sets the file where this server instance is serialized.
	 * 
	 * @param file the file in the workspace where the server instance
	 *    is serialized, or <code>null</code> if the information is
	 *    instead to be persisted with the workspace but not with any
	 *    particular workspace resource
	 */
	public void setFile(IFile file) {
		this.file = file;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.server.core.IServerWorkingCopy#isDirty()
	 */
	public boolean isDirty() {
		return wch.isDirty();
	}

	public ServerDelegate getWorkingCopyDelegate(IProgressMonitor monitor) {
		// make sure that the regular delegate is loaded 
		//getDelegate();
		
		if (workingCopyDelegate != null || serverType == null)
			return workingCopyDelegate;
		
		synchronized (this) {
			if (workingCopyDelegate == null) {
				try {
					long time = System.currentTimeMillis();
					workingCopyDelegate = ((ServerType) serverType).createServerDelegate();
					InternalInitializer.initializeServerDelegate(workingCopyDelegate, this, monitor);
					if (Trace.PERFORMANCE) {
						Trace.trace(Trace.STRING_PERFORMANCE,
								"ServerWorkingCopy.getWorkingCopyDelegate(): <" + (System.currentTimeMillis() - time)
										+ "> " + getServerType().getId());
					}
				} catch (Exception e) {
					if (Trace.SEVERE) {
						Trace.trace(Trace.STRING_SEVERE, "Could not create delegate " + toString(), e);
					}
				}
			}
		}
		return workingCopyDelegate;
	}

	protected ServerBehaviourDelegate getBehaviourDelegate(IProgressMonitor monitor) {
		if (server == null)
			return null;
		
		if (behaviourDelegate != null)
			return behaviourDelegate;
		
		synchronized (this) {
			if (behaviourDelegate == null)
				behaviourDelegate = server.getBehaviourDelegate(monitor);
		}
		return behaviourDelegate;
	}

	public void dispose() {
		// behaviour delegate is cached from the original server
		behaviourDelegate = null;
		
		super.dispose();
		if (workingCopyDelegate != null)
			workingCopyDelegate.dispose();
	}

	public IServer save(boolean force, IProgressMonitor monitor) throws CoreException {
		monitor = ProgressUtil.getMonitorFor(monitor);
		monitor.subTask(NLS.bind(Messages.savingTask, getName()));
		
		if (!force && getOriginal() != null)
			wch.validateTimestamp(((Server)getOriginal()).getTimestamp());
		
		int timestamp = getTimestamp();
		map.put(PROP_TIMESTAMP, Integer.toString(timestamp+1));
		
		if (server == null) {
			server = new Server(file);
			server.setServerState(serverState);
			server.publishListeners = publishListeners;
			server.notificationManager = notificationManager;
		}
		
		if (getServerType() != null && getServerType().hasServerConfiguration()) {
			IFolder folder = getServerConfiguration();
			if (folder == null) {
				folder = ServerType.getServerProject().getFolder(getName() + "-config");
				if (!folder.exists())
					folder.create(true, true, null);
				setServerConfiguration(folder);
			}
		}
		
		server.setInternal(this);
		server.doSave(monitor);
		if (getServerType() != null && getServerType().hasServerConfiguration()) {
			IFolder folder = getServerConfiguration();
			if (folder != null) {
				IProject project = folder.getProject();
				if (project != null && !project.exists()) {
					project.create(null);
					project.open(null);
					ServerPlugin.getProjectProperties(project).setServerProject(true, monitor);
				}
				if (!folder.exists())
					folder.create(IResource.FORCE, true, null);
			}
		}
		if (getWorkingCopyDelegate(monitor) != null)
			getWorkingCopyDelegate(monitor).saveConfiguration(monitor);
		wch.setDirty(false);
		
		if (getServerState() == IServer.STATE_STARTED)
			autoPublish();
		
		return server;
	}

	public IServer saveAll(boolean force, IProgressMonitor monitor) throws CoreException {
		if (runtime != null && runtime.isWorkingCopy()) {
			IRuntimeWorkingCopy wc = (IRuntimeWorkingCopy) runtime;
			wc.save(force, monitor);
		}
		
		return save(force, monitor);
	}

	/**
	 * Add a property change listener to this server.
	 *
	 * @param listener java.beans.PropertyChangeListener
	 */
	public void addPropertyChangeListener(PropertyChangeListener listener) {
		if (listener == null)
			throw new IllegalArgumentException("Listener cannot be null");
		wch.addPropertyChangeListener(listener);
	}
	
	/**
	 * Remove a property change listener from this server.
	 *
	 * @param listener java.beans.PropertyChangeListener
	 */
	public void removePropertyChangeListener(PropertyChangeListener listener) {
		if (listener == null)
			throw new IllegalArgumentException("Listener cannot be null");
		wch.removePropertyChangeListener(listener);
	}

	/**
	 * Fire a property change event.
	 * 
	 * @param propertyName a property name
	 * @param oldValue the old value
	 * @param newValue the new value
	 */
	public void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) {
		wch.firePropertyChangeEvent(propertyName, oldValue, newValue);
	}

	public void addServerListener(IServerListener listener) {
		if (server != null)
			server.addServerListener(listener);
		else
			super.addServerListener(listener);
	}

	public void removeServerListener(IServerListener listener) {
		if (server != null)
			server.removeServerListener(listener);
		else
			super.removeServerListener(listener);
	}

	public void addPublishListener(IPublishListener listener) {
		if (server != null)
			server.addPublishListener(listener);
		else
			super.addPublishListener(listener);
	}

	public void removePublishListener(IPublishListener listener) {
		if (server != null)
			server.removePublishListener(listener);
		else
			super.removePublishListener(listener);
	}

	public void setRuntime(IRuntime runtime) {
		this.runtime = runtime;
		if (runtime != null)
			setAttribute(RUNTIME_ID, runtime.getId());
		else
			setAttribute(RUNTIME_ID, (String)null);
	}

	public void setRuntimeId(String runtimeId) {
		setAttribute(RUNTIME_ID, runtimeId);
		resolve();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.server.core.IServer#modifyModule(org.eclipse.wst.server.core.model.IModule)
	 */
	public void modifyModules(IModule[] add, IModule[] remove, IProgressMonitor monitor) throws CoreException {
		// null checks are in canModifyModules
		IStatus status = canModifyModules(add, remove, monitor);
		if (status != null && status.getSeverity() == IStatus.ERROR)
			throw new CoreException(status);
		
		try {
			monitor = ProgressUtil.getMonitorFor(monitor);
			monitor.subTask(Messages.taskModifyModules);
			getWorkingCopyDelegate(monitor).modifyModules(add, remove, monitor);
			wch.setDirty(true);
			
			// trigger load of modules list
			getModules();
			
			if (add != null) {
				int size = add.length;
				for (int i = 0; i < size; i++) {
					if (!modules.contains(add[i])) {
						modules.add(add[i]);
						resetState(new IModule[] { add[i] }, monitor);
					}
				}
			}
			
			if (remove != null) {
				int size = remove.length;
				externalModules = getExternalModules();
				for (int i = 0; i < size; i++) {
					if (modules.contains(remove[i])) {
						modules.remove(remove[i]);
						resetState(new IModule[] { remove[i] }, monitor);
					}
					if (externalModules != null && externalModules.contains(remove[i])) {
						externalModules.remove(remove[i]);
						resetState(new IModule[] { remove[i] }, monitor);
					}
				}
			}
			
			// convert to attribute
			List<String> list = new ArrayList<String>();
			Iterator iterator = modules.iterator();
			while (iterator.hasNext()) {
				IModule module = (IModule) iterator.next();
				StringBuffer sb = new StringBuffer(module.getName());
				sb.append("::");
				sb.append(module.getId());
				IModuleType mt = module.getModuleType();
				if (mt != null) {
					sb.append("::");
					sb.append(mt.getId());
					sb.append("::");
					sb.append(mt.getVersion());
				}
				list.add(sb.toString());
			}
			setAttribute(MODULE_LIST, list);
			resetOptionalPublishOperations();
			resetPreferredPublishOperations();
		} catch (CoreException ce) {
			throw ce;
		} catch (Exception e) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate modifyModule() " + toString(), e);
			}
			throw new CoreException(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, "" + e.getLocalizedMessage(), e));
		}
	}

	protected void resetState(IModule[] module, IProgressMonitor monitor) {
		setModulePublishState(module, PUBLISH_STATE_UNKNOWN);
		setModuleState(module, IServer.STATE_UNKNOWN);
		setModuleRestartState(module, false);
		setModuleStatus(module, null);
		try {
			IModule[] children = getChildModules(module, monitor);
			int size = children.length;
			int size2 = module.length;
			for (int i = 0; i < size; i++) {
				IModule[] child = new Module[size2 + 1];
				System.arraycopy(module, 0, child, 0, size2);
				child[size2] = children[i];
				resetPublishState(child, monitor);
				setModuleState(module, IServer.STATE_UNKNOWN);
				setModuleRestartState(module, false);
				setModuleStatus(module, null);
			}
		} catch (Exception e) {
			// ignore
		}
	}

	/**
	 * 
	 * @param module
	 * @param monitor
	 * @deprecated use resetState() instead
	 */
	protected void resetPublishState(IModule[] module, IProgressMonitor monitor) {
		setModulePublishState(module, PUBLISH_STATE_UNKNOWN);
		try {
			IModule[] children = getChildModules(module, monitor);
			int size = children.length;
			int size2 = module.length;
			for (int i = 0; i < size; i++) {
				IModule[] child = new Module[size2 + 1];
				System.arraycopy(module, 0, child, 0, size2);
				child[size2] = children[i];
				resetPublishState(child, monitor);
			}
		} catch (Exception e) {
			// ignore
		}
	}

	/**
	 * Sets the defaults for this server, including the name. This method should be
	 * called when creating a server, or when any major settings (e.g. runtime, host)
	 * change.
	 * 
	 * @param monitor a progress monitor, or null
	 */
	public void setDefaults(IProgressMonitor monitor) {
		try {
			ServerUtil.setServerDefaultName(this);
			getWorkingCopyDelegate(monitor).setDefaults(monitor);
		} catch (Exception e) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate setDefaults() " + toString(), e);
			}
		}
	}

	public void renameFiles(IProgressMonitor monitor) throws CoreException {
		if (getServerConfiguration() != null) {
			IFolder folder = getServerConfiguration();
			IFolder folder2 = ServerType.getServerProject().getFolder(getName() + "-config");
			folder.move(folder2.getFullPath(), true, true, monitor);
			setServerConfiguration(folder2);
			save(true, monitor);
		}
		
		if (file != null) {
			IFile file2 = ServerUtil.getUnusedServerFile(file.getProject(), this);
			file.move(file2.getFullPath(), true, true, monitor);
		}
	}

	/*
	 * Publish to the server using the progress monitor. The result of the
	 * publish operation is returned as an IStatus.
	 */
	public IStatus publish(int kind, IProgressMonitor monitor) {
		if (server != null)
			return server.publish(kind, monitor);
		return new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishing, null);
	}

	public void publish(int kind, List<IModule[]> modules2, IAdaptable info, IOperationListener listener) {
		if (server != null) {
			server.publish(kind, modules2, info, listener);
			return;
		}
		listener.done(new Status(IStatus.ERROR, ServerPlugin.PLUGIN_ID, 0, Messages.errorPublishing, null));
	}

	public ILaunch getLaunch() {
		if (server != null)
			return server.getLaunch();
		return null;
	}

	public ILaunchConfiguration getLaunchConfiguration(boolean create, IProgressMonitor monitor) throws CoreException {
		if (server != null)
			return server.getLaunchConfiguration(create, monitor);
		return null;
	}

	/**
	 * Sets the server restart state.
	 *
	 * @param state boolean
	 */
	public void setServerRestartState(boolean state) {
		if (server != null)
			server.setServerRestartState(state);
		else
			super.setServerRestartState(state);
	}

	/**
	 * @see IServer#getAdapter(Class)
	 */
	public Object getAdapter(Class adapter) {
		if (workingCopyDelegate != null) {
			if (adapter.isInstance(workingCopyDelegate))
				return workingCopyDelegate;
		}
		if (delegate != null) {
			if (adapter.isInstance(delegate))
				return delegate;
		}
		if (behaviourDelegate != null) {
			if (adapter.isInstance(behaviourDelegate))
				return behaviourDelegate;
		}
		return Platform.getAdapterManager().getAdapter(this, adapter);
	}

	/**
	 * @see IServer#loadAdapter(Class, IProgressMonitor)
	 */
	public Object loadAdapter(Class adapter, IProgressMonitor monitor) {
		getWorkingCopyDelegate(monitor);
		if (adapter.isInstance(workingCopyDelegate))
			return workingCopyDelegate;
		
		getDelegate(monitor);
		if (adapter.isInstance(delegate))
			return delegate;
		
		getBehaviourDelegate(monitor);
		if (adapter.isInstance(behaviourDelegate))
			return behaviourDelegate;
		
		return Platform.getAdapterManager().loadAdapter(this, adapter.getName());
	}

	/**
	 * Import the server configuration from the given runtime.
	 * 
	 * @param runtime2
	 * @param monitor
	 * @deprecated should use importRuntimeConfiguration() instead
	 */
	public void importConfiguration(IRuntime runtime2, IProgressMonitor monitor) {
		try {
			getWorkingCopyDelegate(monitor).importConfiguration(runtime2, monitor);
		} catch (Exception e) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate importConfiguration() " + toString(), e);
			}
		}
	}

	/**
	 * Import the server configuration from the given runtime.
	 * 
	 * @param runtime2 a server runtime
	 * @param monitor a progress monitor, or <code>null</code> if progress
	 *    reporting and cancellation are not desired
	 * @throws CoreException if there is any problem importing the configuration
	 *    from the runtime
	 */
	public void importRuntimeConfiguration(IRuntime runtime2, IProgressMonitor monitor) throws CoreException {
		try {
			getWorkingCopyDelegate(monitor).importRuntimeConfiguration(runtime2, monitor);
		} catch (CoreException ce) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "CoreException calling delegate importConfiguration() " + toString(),
						ce);
			}
			throw ce;
		} catch (Exception e) {
			if (Trace.SEVERE) {
				Trace.trace(Trace.STRING_SEVERE, "Error calling delegate importConfiguration() " + toString(), e);
			}
		}
	}

	public void setExternalModules(IModule[] modules) {
		if (server != null)
			server.setExternalModules(modules);
		super.setExternalModules(modules);
	}

	public List<IModule> getExternalModules() {
		if (server != null)
			return server.getExternalModules();
		return super.getExternalModules();
	}

	/*
	 * Break connection with the original server so that this working copy can
	 * be duplicated. The name *must* be set afterwards to change the id. 
	 */
	public void disassociate() {
		server = null;
		if (getAttribute(PROP_LOCKED, false))
			setAttribute(PROP_LOCKED, false);
		if (getAttribute(PROP_ID_SET, false))
			setAttribute(PROP_ID_SET, false);
	}
	
	/**
	 * Checks if a given attribute can be modified, throws an IllegalArgumentException if otherwise 
	 * @param attributeName
	 */
	protected void canModifyAttribute(String attributeName){
		if (attributeName != null && 
				PROP_TIMESTAMP.equalsIgnoreCase(attributeName))			
			throw new IllegalArgumentException("Unmodifiable attribute: "+ attributeName);
	}

	public String toString() {
		return "ServerWorkingCopy " + getId();
	}
}