/*******************************************************************************
 * Copyright (c) 1997-2007 by ProSyst Software GmbH
 * http://www.prosyst.com
 * 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:
 *    ProSyst Software GmbH - initial API and implementation
 *******************************************************************************/
package org.eclipse.equinox.internal.ip.impl;

import java.io.*;
import java.lang.reflect.*;
import java.net.*;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.equinox.internal.ip.ProvisioningInfoProvider;
import org.eclipse.equinox.internal.ip.ProvisioningStorage;
import org.eclipse.equinox.internal.util.timer.Timer;
import org.eclipse.equinox.internal.util.timer.TimerListener;
import org.osgi.framework.*;
import org.osgi.service.provisioning.ProvisioningService;

/**
 * Class implementing provisioning management based on OSGi RFC 27. On start
 * this <I>BundleActivator</I> gets its manifest headers
 * <I>ProvisioningAgent.providerS</I> and <I>ProvisioningAgent.STORAGE</I>.
 * Using them it decides which <I>ProvisioningInfoProvider</I>-s and which
 * <I>ProvisioningStorage</I> are packed in the bundle. It make instances them.
 * To be succesfull instantiation they MUST have constructor without parameters.
 * All packed in bundle providers that implement <I>BundleActivator</I>. Their
 * methods <I>start(BundleContext)</I> are invoked after instantiation. (On
 * stop their <I>stop(BundleContext)</I>-s are invoked). ProvisioningStorage is
 * used for saving provisioning service data. If no such storage thatas are lost
 * on restart of bundle. Any fail in provider/storage instantiation, providers
 * casting to <I>BundleActivator</I> ends with exception in bundle start and
 * bundle will not reach state ACTIVE.
 * 
 * Also it starts DiscoveryAgent which is prosyst's feature. It is constructed
 * using values of system properties: "equinox.multicast.host" as host and
 * "equinox.multicast.port" as port. If one of these properties is null no
 * instance of DiscoveryAgent is made.
 * 
 * @author Avgustin Marinov
 * @author Pavlin Dobrev
 * @version 1.0
 */

public class ProvisioningAgent implements BundleActivator, ProvisioningService, ServiceListener, FrameworkListener, TimerListener {

	/**
	 * This manifest header determines the packed into the provisioning agent
	 * bundle storage (if such exists) that is to be setarted.
	 */
	public final static String STORAGE = "Prv-Storage";

	/**
	 * This manifest header determines URL Handlers packed into the provisioning
	 * agent bundle that are to be started.
	 */
	public final static String URL_HANDLERS = "Url-Handlers";

	/** This system property that determines multicast host for discoverer agent. */
	public final static String MULTICAST_HOST = "equinox.provisioning.multicast.host";

	/** This system property taht determines multicast port for discoverer agent. */
	public final static String MULTICAST_PORT = "equinox.provisioning.multicast.port";

	/**
	 * This system property determines if provisioning can use HTTP transport
	 * (assumed as unsecured) for provisioning data assignments.
	 */
	public final static String HTTP_ALLOWED = "equinox.provisioning.httpprv.allowed";

	/**
	 * This system property determines if provisioning must waits until the
	 * framework is started.
	 */
	public final static String WAIT_FW_START = "equinox.provisioning.prv.fwstart";

	/**
	 * This system property determines if provisioning should try to make
	 * provisioning on every start
	 */
	public final static String REPROVISIONING_ON_START = "equinox.provisioning.reprovision.onstart";

	/**
	 * Close Zip after reading.
	 */
	public final static String CLOSE_ZIP = "equinox.provisioning.close.zip";

	/**
	 * This system property determines if provisioning agent should print debug
	 * and error information on the console.
	 */
	public final static String DEBUG = "equinox.provisioning.debug";

	/**
	 * This system property determines if provisioning agent should print debug
	 * and error information on the console.
	 */
	public final static String REMOTE_DEBUG = "equinox.provisioning.remote.debug";

	/** BundleContext used for interactions with framework. */
	public static BundleContext bc;

	/** Provisioning data. */
	private ProvisioningData info;
	/** Registration of ProvisioningService. */
	private ServiceRegistration sreg;
	/**
	 * Configuration store used for data storing. It is null after start if no
	 * storage packed in bundle.
	 */
	private ProvisioningStorage storage;

	/** If HTTP protocol is allows for provisioning data assignments. */
	private boolean httpAllowed;

	/**
	 * If storage is inner packed but it is not inner provider, and is
	 * BundleActivator and its start method has been invoked, it must be
	 * stopped.
	 */
	private boolean destroyStorageOnStop = false;

	/**
	 * Contains providers packed in bundle. It can be null after start if no
	 * providers packed in bundle.
	 */
	private Vector providers;

	/**
	 * Contains URL handlers packed in bundle. It can be null after start if no
	 * providers packed in bundle.
	 */
	private Vector urlHandlers;

	/**
	 * DiscoveryAgent instantiated by this object on start(BundleContext). It is
	 * null after start id host or port arenot set in manifest.
	 */
	private Runnable da;

	/** If there is need to wait for start of framework. */
	private boolean wfs;
	/** If the information is added and provistioning assignements are allowed. */
	private boolean active;
	/**
	 * Flag if the start data is processed from frameworkEvent or from
	 * start(BundleContext) method.
	 */
	private boolean startProcessed;
	/** If to do reprovisiong */
	private boolean reprovision;
	/**
	 * If the service is already registered. Used to be avided duplicated
	 * registration on start.
	 */
	private boolean registered;
	/** If to close zip after reading */
	private boolean closeZip;

	// =================================================================================//
	private static final int PROVISIONING = 1;

	private static final String HAS_FAILED_PROVISIONG = "!@#$_hasFailedPrv";

	private boolean reAfterPrvFailureDisabled;
	private int a;
	private int b;
	private int changePeriod;
	private int maxPeriod;

	private Timer timer;
	private long nextProvisioningAfter;
	private int times;
	// =================================================================================//

	public final static int ERROR_UNKNOWN = 0;
	public final static int ERROR_LOAD_STORE_DATA = 1;
	public final static int ERROR_MALFORMED_URL = 2;
	public final static int ERROR_IO_EXCEPTION = 3;
	public final static int ERROR_CORRUPTED_ZIP = 4;

	/**
	 * Invoked by framework on bundle start.
	 * 
	 * @param bc
	 *            bundle context
	 * @exception java.lang.Exception
	 *                mostly when manifest dont match to packed
	 *                providers/storage or their implementation do not match
	 *                expectations.
	 */
	public void start(BundleContext bc) throws Exception {
		ProvisioningAgent.bc = bc;
		active = false;
		startProcessed = false;
		wfs = true;
		if (bc.getProperty(WAIT_FW_START) != null)
			if (bc.getProperty(WAIT_FW_START).equals("false"))
				wfs = false;
		httpAllowed = true;
		if (bc.getProperty(HTTP_ALLOWED) != null)
			if (bc.getProperty(HTTP_ALLOWED).equals("false"))
				httpAllowed = false;
		reprovision = getBoolean(ProvisioningAgent.REPROVISIONING_ON_START);
		closeZip = getBoolean(CLOSE_ZIP);

		// =================================================================================//
		reAfterPrvFailureDisabled = getBoolean("equinox.provisioning.provisioning.reAfterPrvFailure.disabled");
		a = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.a", 60000);
		b = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.b", 60000);
		changePeriod = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.changePeriod", 300000);
		maxPeriod = getInteger("equinox.provisioning.provisioning.reAfterPrvFailure.maxperiod", 3600000);
		nextProvisioningAfter = a;
		// =================================================================================//
		Log.j9workAround = getBoolean("equinox.provisioning.j9.2.0.workaround");
		Log.debug = getBoolean(DEBUG);
		Log.remoteDebug = getBoolean(REMOTE_DEBUG);
		Log.sendTrace = getBoolean("equinox.provisioning.send.trace");
		Log.prvSrv = this;

		org.eclipse.equinox.internal.util.ref.Log log = new org.eclipse.equinox.internal.util.ref.Log(bc);
		log.setDebug(true); // always log to LogService!
		log.setPrintOnConsole(Log.debug);
		Log.log = log;

		try {
			start0(bc);
		} catch (Exception exc) {
			Log.log.close();
			Log.log = null;
			throw exc;
		}
	}

	private void start0(BundleContext bc) throws Exception {
		Log.debug("Starting provisioning agent ...");

		Bundle thisBundle = bc.getBundle();

		// Starts URL handlers packed into the provisioning bundle
		String urlHandlersHeader = (String) thisBundle.getHeaders().get(URL_HANDLERS);
		if (urlHandlersHeader != null) {
			StringTokenizer strTok = new StringTokenizer(urlHandlersHeader, ", ");
			urlHandlers = new Vector(strTok.countTokens());
			while (strTok.hasMoreTokens()) {
				try {
					BundleActivator handler = (BundleActivator) Class.forName(strTok.nextToken().trim()).newInstance();
					handler.start(bc);
					urlHandlers.addElement(handler);
				} catch (Exception e) {
					Log.debug("Can't instantiate or start a handler!");
					throw e;
				}
			}
			urlHandlersHeader = null;
		}

		// Gets inner storage activator class name (if inner storage exists).
		String storageName = (String) thisBundle.getHeaders().get(STORAGE);
		if (storageName != null) {
			storageName.trim();
		}

		// Registers configuration providers packed into the bundle
		String providersHeader = (String) thisBundle.getHeaders().get(ProvisioningInfoProvider.PROVIDERS);
		if (providersHeader != null) {
			providers = new Vector(5);
			StringTokenizer strTok = new StringTokenizer(providersHeader, ",; ");
			while (strTok.hasMoreTokens()) {
				String providerName = strTok.nextToken().trim();
				strTok.nextToken(); // Skips ranking
				Object provider = Class.forName(providerName).newInstance();
				if (provider instanceof BundleActivator) {
					((BundleActivator) provider).start(bc);
				}
				if (providerName.equals(storageName)) {
					storage = (ProvisioningStorage) provider;
					destroyStorageOnStop = true;
				}
				providers.addElement(provider);
			}
		}

		if (storage == null && storageName != null && storageName.length() != 0) {
			try {
				storage = (ProvisioningStorage) Class.forName(storageName).newInstance();
				if (storage instanceof BundleActivator) {
					((BundleActivator) storage).start(bc);
					destroyStorageOnStop = true;
				}
			} catch (Exception e) {
				Log.debug("Can't instantiate or start storage \"" + storage + "\"!");
				throw e;
			}
		}

		info = new ProvisioningData();

		if (storage == null) {
			synchronized (this) {
				bc.addServiceListener(this, "(|" + '(' + Constants.OBJECTCLASS + '=' + ProvisioningStorage.class.getName() + ")" + '(' + Constants.OBJECTCLASS + '=' + ProvisioningInfoProvider.class.getName() + ")" + '(' + Constants.OBJECTCLASS + '=' + Timer.class.getName() + ')' + ")");

				storage = getStorage();
			}
		} else {
			bc.addServiceListener(this, "(|" + '(' + Constants.OBJECTCLASS + '=' + ProvisioningInfoProvider.class.getName() + ')' + '(' + Constants.OBJECTCLASS + '=' + Timer.class.getName() + ')' + ")");
		}

		synchronized (this) {
			if (timer == null) {
				ServiceReference sRef = bc.getServiceReference(Timer.class.getName());
				if (sRef != null) {
					timer = (Timer) bc.getService(sRef);
				}
			}
		}

		if (storage != null) {
			Log.debug("Loads from " + storage + " storage.");
			try {
				Dictionary storedInfo = storage.getStoredInfo();
				if (storedInfo != null && storedInfo.size() != 0) {
					info.add(storedInfo);
				}
			} catch (Exception e) { // NPE or storage specific exception can be
				// thrown
				Log.debug(e);
				setError(ERROR_LOAD_STORE_DATA, e.toString());
				if (destroyStorageOnStop) {
					Log.debug("Warning: the storage could be unavailable!");
				} else {
					storage = null;
				}
			}
		}

		if (getHasFailedPrv() && !reAfterPrvFailureDisabled) {
			reprovision = true;
		}

		boolean hasLoadedInfo = false;

		ServiceReference[] srefs = bc.getServiceReferences(ProvisioningInfoProvider.class.getName(), null);
		if (srefs != null) {
			sort(srefs);
			for (int i = 0; i < srefs.length; i++) {
				ProvisioningInfoProvider provider = ((ProvisioningInfoProvider) bc.getService(srefs[i]));
				try {
					synchronized (info) {
						if (!info.providers.contains(provider)) {
							Log.debug("Loads from " + provider + " provider.");
							info.providers.addElement(provider);
							Dictionary toAdd = provider.init(this);
							if (toAdd != null && toAdd.size() != 0) {
								String prvref = (String) toAdd.get(ProvisioningService.PROVISIONING_REFERENCE);
								if (prvref != null && prvref.trim().length() != 0) { // reference
									// is
									// changed
									// by
									// loader
									reprovision = true;
								}
								info.add(toAdd);
								hasLoadedInfo = true;
							}
						}
					}
				} catch (Exception e) {
					Log.debug(e);
				}
			}
		}

		if (!isFrameworkStarted()) {
			bc.addFrameworkListener(this);
		} else {
			wfs = false;
		}

		if (hasLoadedInfo) {
			store();
		}
		active = true;
		processStart();

		// Join GW to a multicast host.
		try {
			String host = "225.0.0.0";
			if (bc.getProperty(MULTICAST_HOST) != null)
				host = bc.getProperty(MULTICAST_HOST);
			String port = Integer.toString(getInteger(MULTICAST_PORT, 7777));
			if (host.length() != 0 && port.length() != 0) {
				Class dscAgentClass = Class.forName("org.eclipse.equinox.internal.ip.impl.dscagent.DiscoveryAgent");
				Constructor constr = dscAgentClass.getConstructor(new Class[] {String.class, int.class, BundleContext.class, ProvisioningAgent.class});
				new Thread(da = (Runnable) constr.newInstance(new Object[] {host, new Integer(Integer.parseInt(port)), bc, this}), "Discovery Agent").start();
			} // "info" is already initialized
		} catch (Throwable t) {
			Log.debug("Can't create discovery agent!");
		}
		Log.debug("Provisioning agent started ...");
	}

	/**
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext bc) throws Exception {
		Log.debug("Stopping provisionig agent ...");

		if (timer != null) {
			try {
				timer.removeListener(this, PROVISIONING);
			} catch (Throwable _) {
			}
			timer = null;
		}

		registered = false;

		try {
			bc.removeServiceListener(this);
		} catch (Exception _) {
		}

		try {
			bc.removeFrameworkListener(this);
		} catch (Exception _) {
		}

		if (sreg != null) {
			try {
				sreg.unregister();
			} catch (Exception _) {
			}
			sreg = null;
		} // Unregisters ProvisioningService

		if (da != null) {
			try {
				Method close = da.getClass().getMethod("close", new Class[] {});
				close.invoke(da, new Object[0]);
			} catch (Exception e) {
				Log.debug(e);
			}
			da = null;
		} // Closes DiscoveryAgent

		if (storage != null) {
			if (destroyStorageOnStop) {
				try {
					if (storage instanceof BundleActivator) {
						((BundleActivator) storage).stop(bc);
					}
				} catch (Exception e) {
					Log.debug(e);
				}
				destroyStorageOnStop = false;
			}
			storage = null;
		} // Stores data

		if (providers != null) {
			for (int i = providers.size(); i-- > 0;) {
				try {
					((BundleActivator) providers.elementAt(i)).stop(bc);
				} catch (Exception e) {
					Log.debug(e);
				}
			}
			providers = null;
		} // Stops providers

		if (urlHandlers != null) {
			for (int i = urlHandlers.size(); i-- > 0;) {
				try {
					((BundleActivator) urlHandlers.elementAt(i)).stop(bc);
				} catch (Exception e) {
					Log.debug(e);
				}
			}
			urlHandlers = null;
		} // Stops providers

		info = null;
		Log.debug("Provisioning agent stopped ...");
		Log.log.close();
		Log.log = null;
	}

	public Dictionary getInformation() {
		return info;
	}

	public void setInformation(Dictionary info) {
		boolean refChanged = info.get(ProvisioningService.PROVISIONING_REFERENCE) != null;
		synchronized (this.info) {
			Integer version = (Integer) this.info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
			Integer newVersion = new Integer(version.intValue() + 1);
			this.info.set(info);
			incrementUC(newVersion);
		}
		modify();
		updated(refChanged);
	}

	public void addInformation(Dictionary info) {
		addInformation(info, null);
	}

	private static final ByteArrayOutputStream baos = new ByteArrayOutputStream();
	private static final byte[] buffer = new byte[1024];

	private static byte[] readStream(InputStream is) throws IOException {
		synchronized (buffer) {
			baos.reset();
			int read;
			while ((read = is.read(buffer, 0, buffer.length)) != -1) {
				baos.write(buffer, 0, read);
			}
			return baos.toByteArray();
		}
	}

	private Bundle installBundle(String name, InputStream is) {
		Bundle bundle = null;
		try {
			bundle = getBundle(name);
			if (bundle == null) { /* install the bundle */
				if (Log.debug)
					Log.debug("Installing management bundle '" + name + "'");
				bundle = bc.installBundle(name, is);
			} else { /* just update it */
				if (Log.debug)
					Log.debug("Updating management bundle '" + name + "'");
				bundle.update(is);
			}
		} catch (Throwable t) {
			setHasFailedPrv(true);
			Log.debug("WARNING: Failed to install management bundle '" + name + "'", t);
		}
		return bundle;
	}

	public void addInformation(ZipInputStream zis) {
		Log.debug("Add Information form ZIS.");
		Hashtable entries = new Hashtable(2);//cache for unprocessed entries 
		boolean manifestFound = false;
		Dictionary info = new Hashtable(5);
		Dictionary entriesFromHeader = null;
		Dictionary extraFileds = null;
		Vector bundlesToStart = new Vector(5);
		String header = null;
		try {
			ZipEntry ze;
			String name, type;
			/* read the rest of the entries */
			while ((ze = zis.getNextEntry()) != null) {
				/* read name */
				name = ze.getName();
				if (name.endsWith("/")) {// path entry
					zis.closeEntry();
					continue;

				}
				if (name.charAt(0) == '/')
					name = name.substring(1);
				/* read extra */
				byte[] extra = ze.getExtra();
				type = extra == null ? null : new String(extra).toLowerCase();
				if (extra != null && !"META-INF/MANIFEST.MF".equals(name)) {
					if (extraFileds == null) {
						extraFileds = new Hashtable(3, 3);
					}
					extraFileds.put(name, type);
				}//the extra field is null or the entry is the manifest
				if (!manifestFound) {
					if ("META-INF/MANIFEST.MF".equals(name)) {//the entry is the manifest
						manifestFound = true;
						header = getHeaderFromManifest(zis);
						entriesFromHeader = filterAttributes(TYPE, parseEntries(header));
					} else {//no manifest yet, so cache the entry
						System.out.println("---put : " + name);
						entries.put(name, readStream(zis));
					}
				} else {//the manifest is found so we process the entry
					processEntry(extraFileds, name, null, zis, info, entriesFromHeader, bundlesToStart);
				}
				zis.closeEntry();
			}

			/*process the cached entries*/
			Enumeration names = entries.keys();
			while (names.hasMoreElements()) {
				processEntry(extraFileds, name = (String) names.nextElement(), (byte[]) entries.get(name), null, info, entriesFromHeader, bundlesToStart);
			}
		} catch (Throwable e) {
			this.info.setError(ERROR_CORRUPTED_ZIP, e.toString());
			Log.debug("Error reading provisioning package", e);
			setHasFailedPrv(true);
		}

		/* close the zip file */
		if (closeZip) {
			try {
				zis.close();
			} catch (Exception _) {
			}
		}

		/* update info and start all required bundles */
		addInformation(info, bundlesToStart); // bundle should
	}

	private void processEntry(Dictionary extraFileds, String name, byte[] content, InputStream is, Dictionary info, Dictionary entriesFromHeader, Vector bundlesToStart) throws IOException {
		/* 
		* first try the InitialProvisioning-Entries header
		* if the zip file had a manifest entry
		*/
		String type = entriesFromHeader == null ? null : (String) entriesFromHeader.get(name);
		/* 
		 * If there is no value in the InitialProvisioning-Entries header for that path
		 * try to initialize the type from the entry's extra field.
		 * If this ZIP entry field is present, the Initial Provisioning service should not
		 * look further, even if the extra field contains an erroneous value.
		 */
		if (type == null) {
			if (extraFileds != null) {
				type = (String) extraFileds.get(name);
			}
		}
		/*
		* if type is still null try to to initialize it 
		* according to the extension of the entry's name 
		*/
		if (type == null) {
			type = getMIMEfromExtension(name);
		}

		/* process entry */
		if (Log.debug) {
			Log.debug("Processing entry '" + name + "' of type " + type);
		}
		if (MIME_BUNDLE.equals(type) || MIME_BUNDLE_ALT.equals(type)) {
			installBundle(name, content == null ? new ISWrapper(is) : new ISWrapper(new ByteArrayInputStream(content)));
		} else if (MIME_BYTE_ARRAY.equals(type)) {
			info.put(name, content == null ? readStream(is) : content);
		} else if (MIME_STRING.equals(type)) {
			String value = getUTF8String(content == null ? readStream(is) : content);
			info.put(name, value);
			/*
			 * FIXME: actually there can be only ONE key of that type! - so why
			 * using vector
			 */
			if (PROVISIONING_START_BUNDLE.equals(name)) {
				/* Make management agent bundle deployment. Sets java.security.AllPermission
				 * if PermissionAdmin is available..*/
				try {
					grantAllPermissions(value);
				} catch (Throwable e) {
					Log.debug("Failed to grant all permissions", e);
				}
				bundlesToStart.addElement(value);
			}
		} else if (MIME_BUNDLE_URL.equals(type)) {
			String value = getUTF8String(content == null ? readStream(is) : content);
			installBundle(name, new URL(value).openStream());
		} else {
			this.info.setError(ERROR_CORRUPTED_ZIP, //
					"Unknown MIME type (" + type + ") for entry '" + name + "'");
			setHasFailedPrv(true);
		}
	}

	public void serviceChanged(ServiceEvent se) {
		Object service = bc.getService(se.getServiceReference());
		if (service instanceof ProvisioningStorage) {
			if (se.getType() == ServiceEvent.REGISTERED) {
				synchronized (this) {
					if (storage == null) { // If there is a storage it won't be
						// replaced.
						storage = (ProvisioningStorage) service;
					} else {
						return;
					}
				}
				try {
					Object oldUC = info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
					int iOldUC = 0;
					if (oldUC != null && oldUC instanceof Integer) {
						iOldUC = ((Integer) oldUC).intValue();
					}

					Dictionary toAdd = storage.getStoredInfo();
					Object newUC = toAdd.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
					int iNewUC = 0;
					if (newUC != null && newUC instanceof Integer) {
						iNewUC = ((Integer) newUC).intValue();
					}

					boolean refChanged = toAdd.get(ProvisioningService.PROVISIONING_REFERENCE) != null && (iNewUC == 0 || reprovision);

					boolean increment = iNewUC > iOldUC; // In this case it
					// is assummed that
					// is most probably
					// that this
					// is the original version but storage is started after the
					// provisioning bundle.

					synchronized (info) {
						info.set(toAdd);
						if (increment) {
							incrementUC(new Integer(iNewUC));
							modify();
						}
					}

					updated(refChanged);
				} catch (Exception e) {
					Log.debug(e);
				}
				Log.debug("Storage is available.");
			} else if (se.getType() == ServiceEvent.UNREGISTERING) {
				if (storage == bc.getService(se.getServiceReference())) {
					Log.debug("Storage is removed!");
					try {
						storage.store(info);
					} catch (Exception e) {
						Log.debug("Can't store provisioning info!", e);
					}
					storage = null; // No more than one Storage service should
					// be registered on the FW
				}
			}
		}

		if (service instanceof ProvisioningInfoProvider) { // a Storage could
			// be a Provider
			if (se.getType() == ServiceEvent.REGISTERED) {
				ProvisioningInfoProvider provider = (ProvisioningInfoProvider) service;
				Log.debug("Loads from " + provider + " provider.");
				try {
					if (!info.providers.contains(provider)) {
						Dictionary toAdd = provider.init(this);
						boolean refChanged = false;
						if (toAdd != null) {
							String prvref = (String) toAdd.get(ProvisioningService.PROVISIONING_REFERENCE);
							if (prvref != null && prvref.trim().length() != 0) { // reference
								// is
								// changed
								// by
								// loader
								refChanged = true;
							}
						}
						boolean added = true;
						synchronized (info) {
							if (!info.providers.contains(provider)) {
								info.providers.addElement(provider);
								info.add(toAdd);
								if (refChanged) {
									reprovision = true;
								}
								Integer version = (Integer) info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
								Integer newVersion = new Integer(version.intValue() + 1);
								incrementUC(newVersion);
							} else {
								added = false;
							}
						}
						if (added) {
							modify();
							updated(refChanged);
						}
					}
				} catch (Exception e) {
					Log.debug(e);
				}
			} else if (se.getType() == ServiceEvent.UNREGISTERING) {
				info.providers.removeElement(service);
			}
		}

		if (service instanceof Timer) { // timer is expected to be single
			// service
			switch (se.getType()) {
				case ServiceEvent.REGISTERED : {
					synchronized (this) {
						if (timer == null) {
							timer = (Timer) service;
							if (getHasFailedPrv() && !reAfterPrvFailureDisabled) {
								try {
									timer.notifyAfterMillis(this, nextPrvAfter(), PROVISIONING); // TO DO - Won't be
									// updated with newer
									// method - it will not
									// run on older FW
								} catch (Exception e) {
									Log.debug(e);
								}
							}
						}
					}
					break;
				}
				case ServiceEvent.UNREGISTERING : {
					timer = null;
					break;
				}
			}
		}
	}

	public synchronized void timer(int event) {
		Log.debug("Timer event " + event);
		try {
			switch (event) {
				case PROVISIONING : {
					Log.debug("Remake failed provisioning.");
					if (getHasFailedPrv()) {
						processPrvAssignment();
					}
					break;
				}
			}
		} catch (Exception e) {
			Log.debug(e);
		}
	}

	public void frameworkEvent(FrameworkEvent event) {
		if (event.getType() == FrameworkEvent.STARTED) {
			wfs = false;
			processStart();
		}
	}

	public boolean getHttpAllowed() {
		return httpAllowed;
	}

	// Synchronize frameworkEvent and start(BundleContext) initial reactions
	private void processStart() {
		synchronized (this) {
			try {
				Log.debug("Reprovision = " + reprovision + ", update counter = " + info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT) + ", provisioning reference = " + info.get(ProvisioningService.PROVISIONING_REFERENCE));
				if ((reprovision || ((Integer) info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT)).intValue() == 0) && info.get(ProvisioningService.PROVISIONING_REFERENCE) != null) {
					if (!startProcessed) {
						if (processPrvAssignment()) {
							startProcessed = true;
						}
					}
				}
			} catch (Throwable t) {
				Log.debug(t);
			}
		}

		synchronized (this) {
			if (active && !wfs && !registered) {
				registered = true;
			} else {
				return;
			}
		}
		Log.debug("Registering ProvisioningService.");
		sreg = bc.registerService(ProvisioningService.class.getName(), this, getRegProps());
	}

	/**
	 * This is called by ProvisioningData when one puts new
	 * <I>ProvisioningService.PROVISIONING_UPDATE_COUNT</I>.
	 * 
	 * @param refChanged
	 *            if ProvisioningService.PROVISIONING_REFERENCE changed
	 */
	private void updated(boolean refUpdated) {
		Log.debug("ProvisioingDictionary updated. Reference updated = " + refUpdated);

		store();

		synchronized (this) {
			if (refUpdated) {
				if (!processPrvAssignment()) {
					reprovision = true;
				}
			}
		}
	}

	private void store() {
		if (storage != null) {
			try {
				Dictionary info = this.info;
				if (info != null) {
					storage.store(info);
				}
			} catch (Exception e) {
				Log.debug(e);
			}
		} else {
			Log.debug("Warning: No storage available.");
		}
	}

	private boolean processPrvAssignment() {
		if (active && !wfs) {
			new Thread() {
				public void run() {
					try {
						process();
					} catch (Exception e) {
						Log.debug(e);
					}
				}
			}.start();
			return true;
		}
		return false;
	}

	/**
	 * Make provisioning data assignement to nextRef.
	 * 
	 * @param nextRef
	 *            next reference.
	 */
	synchronized void process() {
		if (info == null)
			return; // the bundle is stopped
		setHasFailedPrv(false);
		String ref = (String) info.get(ProvisioningService.PROVISIONING_REFERENCE);
		Log.debug("Reference = \"" + ref + '"');
		if (ref != null && (ref = ref.trim()).length() != 0) {
			String spid = (String) info.get(ProvisioningService.PROVISIONING_SPID);
			Log.debug("Setup from \"" + ref + "\", SPID = " + spid);

			if (!httpAllowed) {
				if (ref.startsWith("http://")) {
					Log.debug("Won't make setup to " + ref + " because http is forbidden!");
					setError(ERROR_MALFORMED_URL, "Provisioning reference is a HTTP URL, but non-secure HTTP is forbidden!");
					setHasFailedPrv(true);
					return;
				}
			}

			if (!ref.startsWith("file:") && ref.indexOf("service_platform_id") == -1) {
				if (ref.indexOf('?') == -1) {
					ref += '?';
				} else {
					ref += '&';
				}
				ref += "service_platform_id" + '=' + URLEncoder.encode(spid == null ? "" : spid);
			}
			Log.debug("Setup url = \"" + ref);

			URLConnection conn = null;

			try {
				URL url = new URL(ref);
				InputStream is = null;

				try {
					conn = url.openConnection();
					if (conn == null) {
						throw new IOException("Can't open connection to " + url + "!");
					}
					conn.setRequestProperty("Connection", "close");

					conn.connect();
					String error = conn.getHeaderField("error"); // Such
					// error
					// message
					// is not by
					// specification
					// and is
					// returned
					// by
					// Provisioining
					// Service
					// Backend
					if (error == null) {
						if ((conn instanceof HttpURLConnection) && ((HttpURLConnection) conn).getResponseCode() != HttpURLConnection.HTTP_OK) {
							String errorMsg = "Warning! ResponseCode = " + ((HttpURLConnection) conn).getResponseCode() + "!";
							Log.debug(errorMsg);
							setError(ERROR_IO_EXCEPTION, errorMsg);
						} else {
							is = conn.getInputStream();
						}
					} else {
						setError(ERROR_IO_EXCEPTION, error);
						Log.debug("Error from Backend: " + error + "! Setup failed!");
					}
				} catch (IOException e) {
					setError(ERROR_IO_EXCEPTION, e.toString());
					Log.debug(e);
				}

				if (is == null) {
					setHasFailedPrv(true);
				} else {
					try {
						ZipInputStream zis = new ZipInputStream(is);
						try {
							addInformation(zis); // the addInformation method
							// closes stream
							Log.debug("Setup ended.");
						} finally {
							if (!closeZip) {
								try {
									zis.close();
								} catch (Exception _) {
								}
							}
						}
					} catch (Exception e) {
						setError(ERROR_CORRUPTED_ZIP, e.toString());
						setHasFailedPrv(true);
						Log.debug(e);
					}
				}
			} catch (IOException e) { // new URL ---> MalformedURLException
				setError(ERROR_MALFORMED_URL, "Invalid Provisioning Reference: " + ref);
			} finally {
				if (conn != null && conn instanceof HttpURLConnection) {
					try {
						((HttpURLConnection) conn).disconnect();
					} catch (Exception _) {
					}
				}
			}
		}

		if (getHasFailedPrv()) {
			if (!reAfterPrvFailureDisabled) {
				try {
					if (timer != null) {
						timer.notifyAfterMillis(this, nextPrvAfter(), PROVISIONING); // TO DO - Won't be updated with
						// newer method - it will not
						// run on older FW
					}
				} catch (Exception e) {
					Log.debug(e);
				}
			}
		} else {
			times = 0;
			nextProvisioningAfter = a;
		}
	}

	private synchronized long nextPrvAfter() {
		times++;
		if (nextProvisioningAfter < maxPeriod && nextProvisioningAfter * times > changePeriod) {
			nextProvisioningAfter += b;
			times = 0;
		}
		Log.debug("Next bootstrap after " + nextProvisioningAfter + "ms");
		return nextProvisioningAfter;
	}

	// bundlesToStart is null on addInfo from provider/storage, and != null on
	// add from ZIS
	// pending error must be cleared only in second case!
	private void addInformation(Dictionary info, Vector bundlesToStart) {
		boolean refChanged = info.get(ProvisioningService.PROVISIONING_REFERENCE) != null;
		synchronized (this.info) {
			this.info.add(info);
			Integer version = (Integer) this.info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
			Integer newVersion = new Integer(version.intValue() + 1);
			incrementUC(newVersion);
		}

		Log.debug("Bundles to start: " + bundlesToStart);
		if (bundlesToStart != null) {
			for (int i = 0; i < bundlesToStart.size(); i++) {
				Object next = bundlesToStart.elementAt(i);
				try {
					if (next instanceof Bundle) {
						((Bundle) next).start();
					} else {
						Bundle b = getBundle((String) next);
						if (b != null) {
							b.start();
						} else {
							Log.debug("Can't find '" + next + "' bundle to start it!");
						}
					}
				} catch (Exception e) {
					Log.debug("Exception while starting " + (next instanceof Bundle ? ((Bundle) next).getLocation() : next), e);
					setHasFailedPrv(true);
					return;
				}
			}

			clearError();
		}

		modify();
		updated(refChanged);
	}

	private boolean isFrameworkStarted() {
		if (!wfs)
			return true;
		Bundle system = bc.getBundle(0);
		return system != null ? system.getState() == Bundle.ACTIVE : true;
	}

	/**
	 * Make management agent bundle deployment. Sets java.security.AllPermission
	 * if PermissionAdmin is available..
	 * 
	 * @param maRef
	 *            management agent reference.
	 */
	private void grantAllPermissions(String location) {
		try {
			ServiceReference sref = bc.getServiceReference("org.osgi.service.permissionadmin.PermissionAdmin"); // the
			// org.osgi.service.permissionadmin is not imported for R1
			if (sref != null) {
				Method method = Class.forName("org.osgi.service.permissionadmin.PermissionAdmin").getMethod("setPermissions", new Class[] {String.class, Class.forName("[Lorg.osgi.service.permissionadmin.PermissionInfo;")});
				Object[] allPerms = (Object[]) Array.newInstance(Class.forName("org.osgi.service.permissionadmin.PermissionInfo"), 1);
				Constructor constr = Class.forName("org.osgi.service.permissionadmin.PermissionInfo").getConstructor(new Class[] {String.class, String.class, String.class});
				allPerms[0] = constr.newInstance(new String[] {"java.security.AllPermission", "", ""});
				method.invoke(bc.getService(sref), new Object[] {location, allPerms});
			}
		} catch (Exception e) {
			Log.debug(e);
		}
	}

	private ProvisioningStorage getStorage() {
		ServiceReference sref = bc.getServiceReference(ProvisioningStorage.class.getName());
		return sref != null ? (ProvisioningStorage) bc.getService(sref) : null;
	}

	private Bundle getBundle(String location) {
		Bundle[] bundles = bc.getBundles();
		for (int i = bundles.length; i-- > 0;) {
			if (location.equalsIgnoreCase(bundles[i].getLocation())) {
				return bundles[i];
			}
		}
		return null;
	}

	private void incrementUC(Integer uc) {
		if (!active) {
			return;
		}
		info.putUC(uc);
	}

	private void modify() {
		if (!active || sreg == null) {
			return;
		}
		try {
			sreg.setProperties(getRegProps());
		} catch (Exception e) {
		}
	}

	private Dictionary getRegProps() {
		Hashtable prvsprops = new Hashtable(1, 1.0F);
		prvsprops.put("Vendor", "ProSyst");
		prvsprops.put(ProvisioningService.PROVISIONING_UPDATE_COUNT, info.get(ProvisioningService.PROVISIONING_UPDATE_COUNT));
		return prvsprops;
	}

	private void sort(ServiceReference[] srefs) {
		for (int i = srefs.length - 1; i > 0; i--) {
			for (int j = 0; j < i; j++) {
				if (less(srefs[j + 1], srefs[j])) {
					ServiceReference temp = srefs[j];
					srefs[j] = srefs[j + 1];
					srefs[j + 1] = temp;
				}
			}
		}
	}

	private boolean less(ServiceReference sref1, ServiceReference sref2) {
		return getRanking(sref1) < getRanking(sref2);
	}

	private int getRanking(ServiceReference sref) {
		Integer ranking = (Integer) sref.getProperty(Constants.SERVICE_RANKING);
		return ranking == null ? 0 : ranking.intValue();
	}

	private String getUTF8String(byte[] body) {
		try {
			return new String(body, "UTF-8");
		} catch (Exception _0) {
			try {
				return new String(body, "UTF8"); // for personal java
				// problems
			} catch (Exception _1) {
				return new String(body);
			}
		}
	}

	private void setError(int code, String message) {
		ProvisioningData data = this.info;
		if (data == null) {
			return;
		}

		data.setError(code, message);

		Integer version = (Integer) data.get(ProvisioningService.PROVISIONING_UPDATE_COUNT);
		Integer newVersion = new Integer(version.intValue() + 1);
		info.putUC(newVersion);

		modify();
	}

	private void clearError() {
		ProvisioningData data = this.info;
		if (data == null) {
			return;
		}

		data.clearError();
	}

	private boolean getHasFailedPrv() {
		return "true".equals(info.get(HAS_FAILED_PROVISIONG));
	}

	private void setHasFailedPrv(boolean hasFailedPrv) {
		if (getHasFailedPrv() != hasFailedPrv) {
			info.putPrivate(HAS_FAILED_PROVISIONG, hasFailedPrv ? "true" : null);
			store();
		}
	}

	/**
	 * Parses the InitialProvisioning-Entries manifest header.
	 * @param header the contents of the InitialProvisioning-Entries manifest header, if any
	 * @return Dictionary which maps entry paths to Dictionary representing the attributes
	 * 		   or null, if no header is found.
	 */
	private static Dictionary parseEntries(String header) {
		Dictionary entries = null;
		Dictionary attributes = null;
		header = removeWhiteSpaces(header);
		if (header == null || header.length() == 0)
			return null;
		int begin = 0, end = 1, length = header.length();
		boolean quoted = false;
		String path, attribute, value;

		entry: while (end != -1 && begin < length - 1) {
			end = readToken(header, begin, false, false); //read the path
			if (end == -1)
				break; //end of header, or only path

			switch (header.charAt(end)) {
				case ';' ://end of path , read attribute
					if (begin == end) {
						end = readToken(header, end + 1, false, true);
						begin = end + 1;
						continue;
					}
					path = header.substring(begin, end);
					begin = end + 1;
					//read the attributes
					while (end != -1 && begin < length - 1) {
						end = readToken(header, begin, quoted, false);
						if (end == -1)
							break entry;
						if (header.charAt(end) != '=' || begin == end) {
							//invalid syntax
							end = readToken(header, begin, false, true); //read the attribute name
							begin = end + 1;
							continue entry;
						}
						attribute = header.substring(begin, end);
						if (header.charAt(begin) == '\"') {
							quoted = true;
							begin = end + 2;
						} else
							begin = end + 1;

						if (begin >= length - 1)
							break entry;

						end = readToken(header, begin, quoted, false); //read the attribute value
						if (end == -1) {
							if (quoted) {
								//invalid syntax
								end = readToken(header, begin, false, true);
								begin = end + 1;
								continue entry;
							}
							//end of header or last attribute-value
							value = header.substring(begin, length);
							if (attributes == null)
								attributes = new Hashtable(2, 3);
							attributes.put(attribute, value);
							begin = end + 1;
							break;
						}
						switch (header.charAt(end)) {
							case ',' : //end of parameters list
								value = header.substring(begin, end);
								if (attributes == null)
									attributes = new Hashtable(2, 3);
								attributes.put(attribute, value);
								if (entries == null)
									entries = new Hashtable(3, 3);
								entries.put(path, attributes);
								attributes = null;
								continue entry;
							case ';' : //another parameter
								value = header.substring(begin, end);
								if (attributes == null)
									attributes = new Hashtable(2, 3);
								attributes.put(attribute, value);
								begin = end + 1;
								continue;
							case '\"' : //endof quoted part
								quoted = false;
								value = header.substring(begin, end - 1);
								if (attributes == null)
									attributes = new Hashtable(2, 3);
								attributes.put(attribute, value);
								begin = end + 1;
								continue;
							default : //invalid syntax
								end = readToken(header, begin, false, true);
								begin = end + 1;
								continue entry;
						}
					}
					break;
				case ',' : //no description
					if (begin == end)
						begin = end + 2;
					else
						begin = end + 1;
					continue;
				default :// invalid syntax
					end = readToken(header, end + 1, false, true);
					begin = end + 1;
					continue;
			}

			if (attributes != null) {
				if (entries == null)
					entries = new Hashtable(3, 3);
				entries.put(path, attributes);
				attributes = null;
			}
		}
		return entries;
	}

	/**
	 * Reads the next token from the manifest header.
	 * @param token the valiue of the manifest header.
	 * @param begin index of the char from which to start
	 * @param quoted if the consequent part of teh string is guoted
	 * @param skipInvalidPath if true all chars till the first comma are skipped
	 * @return the index of the first character from the string which is 
	 *         different from the expected, or -1 if not found
	 */
	private static int readToken(String token, int begin, boolean quoted, boolean skipInvalidPath) {
		char c = 0;
		int len = token.length();
		if (begin >= len)
			return -1;
		if (quoted) {
			while ((c = token.charAt(begin)) != '\"') {
				if (++begin == len)
					return -1;
			}
			return begin;
		}
		if (skipInvalidPath) {
			while ((c = token.charAt(begin)) != ',') {
				if (++begin == len)
					return -1;
			}
			return begin;
		}
		while ((c = token.charAt(begin)) >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c == '_' || c == '-' || c == '/' || c == '.' || c == ':') {
			if (++begin == len)
				return -1;
		}
		return begin;
	}

	static final String TYPE = "type";

	/**
	 * Filters the Dictionary returned from {@link #parseEntries(String)}.
	 * Returns Dictionary which maps entry paths to values of the attribute,
	 * which name is given as argument.
	 */
	private static Dictionary filterAttributes(String attribute, Dictionary entries) {
		if (entries == null)
			return null;
		Dictionary filtered = null;
		Enumeration paths = entries.keys();
		Dictionary attributes = null;
		String path = null, type = null, mime = null;
		while (paths.hasMoreElements()) {
			path = (String) paths.nextElement();
			attributes = (Dictionary) entries.get(path);
			if ((type = (String) attributes.get(attribute)) != null && (mime = typeToMIME(type)) != null) {
				if (filtered == null)
					filtered = new Hashtable(3, 3);
				filtered.put(path, mime);
			}
		}
		return filtered;
	}

	/**
	 * Maps type to an appropriate mime type constant
	 * @param type the value of the type attribute from the InitialProvisioning-Entries header
	 * @return the mime type for the string type or null if type is not a valid type
	 */
	private static String typeToMIME(String type) {
		if ("text".equals(type))
			return ProvisioningService.MIME_STRING;
		if ("binary".equals(type))
			return ProvisioningService.MIME_BYTE_ARRAY;
		if ("bundle".equals(type))
			return ProvisioningService.MIME_BUNDLE;
		if ("bundle-url".equals(type))
			return ProvisioningService.MIME_BUNDLE_URL;
		return null;
	}

	/** 
	 * @param filename the name of the zip entry 
	 * @return the MIME type of the entry according to its extension 
	 *         or null if the mime type cannot be defined
	 */
	static String getMIMEfromExtension(String filename) {
		int index = filename.lastIndexOf(".");
		//no extension -> we cannot identify the type
		if (index == -1)
			return null;
		String extension = filename.substring(index + 1);
		if (extension.equals("jar"))
			return ProvisioningService.MIME_BUNDLE;
		if (extension.equals("txt"))
			return ProvisioningService.MIME_STRING;
		if (extension.equals("url"))
			return ProvisioningService.MIME_BUNDLE_URL;
		return ProvisioningService.MIME_BYTE_ARRAY;
	}

	/**
	 * @param is the InputStream containing the information in the manifest
	 * @return the contents of the InitialProvisioning-Entries header if any or null otherwise 
	 */
	private static String getHeaderFromManifest(InputStream is) {
		boolean blank = false;
		StringBuffer header = new StringBuffer();
		BufferedReader br = new BufferedReader(new InputStreamReader(is));
		String line = null;
		boolean loop = true;
		try {
			while ((line = br.readLine()) != null && loop) {
				if (line.length() == 0) {
					if (blank) {
						break;
					}
					blank = true;
					continue;
				} else {
					blank = false;
				}
				if (line.startsWith(ProvisioningService.INITIALPROVISIONING_ENTRIES)) {
					header.append(removeWhiteSpaces(line.substring(ProvisioningService.INITIALPROVISIONING_ENTRIES.length() + 1)));
					line = br.readLine();//next line
					while (loop = (line.length() != 0 && Character.isWhitespace(line.charAt(0)))) {
						header.append(removeWhiteSpaces(line));
						line = br.readLine();
					}
				}
			}
		} catch (IOException ioe) {
			return null;
		}
		return (header.length() == 0 ? null : header.toString());
	}

	private static String removeWhiteSpaces(String s) {
		if (s == null)
			return null;
		char curr;
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < s.length(); i++) {
			if (!Character.isWhitespace(curr = s.charAt(i))) {
				sb.append(curr);
			}
		}
		return sb.toString();
	}

	private static class ISWrapper extends InputStream {

		private InputStream is;

		ISWrapper(InputStream is) {
			this.is = is;
		}

		public int read() throws IOException {
			return is.read();
		}

		public int read(byte[] src, int off, int len) throws IOException {
			return is.read(src, off, len);
		}

		public void close() {
		}
	}

	public static boolean getBoolean(String property) {
		String prop = (bc != null) ? bc.getProperty(property) : System.getProperty(property);
		return ((prop != null) && prop.equalsIgnoreCase("true"));
	}

	public static int getInteger(String property, int defaultValue) {
		String prop = (bc != null) ? bc.getProperty(property) : System.getProperty(property);
		if (prop != null) {
			try {
				return Integer.decode(prop).intValue();
			} catch (NumberFormatException e) {
				//do nothing
			}
		}
		return defaultValue;
	}
}
