/*******************************************************************************
 * Copyright (c) 2003, 2012 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
			synchronized (modulesLock){
				getModulesWithoutLock();
				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();
	}
}