		java.util.Enumeration enum =  System.getProperties().keys();
		String key = null;
		while (enum.hasMoreElements()){
			key = (String)enum.nextElement();
			System.out.print(key);
			for (int i =0;i<(30-key.length());i++)System.out.print(" ");
			System.out.println("->"+System.getProperty(key));
		}


new java.net.URL("file://C:/temp/org.eclipse.update.core.feature1_1.0.0/org.eclipse.update.core.feature1.plugin1_1.1.1.jar").openStream()

(new java.io.File("C:\\chris chris\hello\\")).mkdirs();

java.net.URL a =  new java.net.URL("http","www.oti.com","/feature/blah.jar");
java.net.URL b =  new java.net.URL("jar",null,a.toExternalForm()+"!/hello.txt");
b

new java.net.URL("file",null,System.getProperty("java.io.tmpdir"));

String tempDir = "c:\\TEMP\\features2.jar";
java.net.URL TEMP_SITE = new java.net.URL("file",null,tempDir);
java.net.URL file = new java.net.URL("jar",null,TEMP_SITE.toExternalForm()+"!/feature.xml");
file.openStream();
file

java.io.File f =  new java.io.File("c:\\temp\\xtf\\file.jar");
f.mkdirs()

java.util.Locale.getDefault()
java.util.ResourceBundle

java.net.URL url = new java.net.URL("file",null,"C:\\path"+java.io.File.separator);
url.getPath().endsWith("/");
url

java.net.URL url = new java.net.URL("http://machine:8080/path space/file.abc#hello");
java.net.URL url2 = new java.net.URL(url,"/ ");
url2.getPath()

java.lang.ClassLoader l = new java.net.URLClassLoader(new java.net.URL[] {new java.net.URL("file",null,"c:\\oti\\wsw205\\eclipse\\install\\features\\org.eclipse.help.feature_1.0.4/") }, null);
java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("feature", java.util.Locale.getDefault(), l);
bundle

String[] ss = {"a", "b"}; 
java.util.List list = new java.util.ArrayList(0);
list.addAll(java.util.Arrays.asList(ss)); 
list.add("c");
list.size();

java.util.List list = new java.util.ArrayList(0);
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
while (list.size()>5){
	list.remove(0);
}
list.get(0)


org.eclipse.update.internal.security.KeyStores k = new org.eclipse.update.internal.security.KeyStores();
while (k.hasNext()){
	org.eclipse.update.internal.security.KeystoreHandle handle = (org.eclipse.update.internal.security.KeystoreHandle) k.next();
	System.out.println("KeyStore:"+handle.getLocation()+":"+handle.getType());
}

*****************************************
OLD Feature Code


	/**
	 */
	private void downloadArchivesLocally(ISite tempSite, String[] archiveIDToInstall, IProgressMonitor monitor) throws CoreException, IOException {

		URL sourceURL;
		String newFile;
		URL newURL;

		if (monitor != null) {
			monitor.beginTask("Download archives bundles to Temporary Space", archiveIDToInstall.length);
		}
		for (int i = 0; i < archiveIDToInstall.length; i++) {

			// transform the id by asking the site to map them to real URL inside the SITE
			if (getSite() != null) {
				sourceURL = getSite().getSiteContentProvider().getArchivesReferences(archiveIDToInstall[i]);
				if (monitor != null) {
					monitor.subTask("..." + archiveIDToInstall[i]);
				}
				// the name of the file in the temp directory
				// should be the regular plugins/pluginID_ver as the Temp site is OUR site
				newFile = Site.DEFAULT_PLUGIN_PATH + archiveIDToInstall[i];
				newURL = UpdateManagerUtils.resolveAsLocal(sourceURL, newFile, monitor);

				// transfer the possible mapping to the temp site						
				 ((Site) tempSite).addArchive(new URLEntry(archiveIDToInstall[i], newURL));
				if (monitor != null) {
					monitor.worked(1);
					if (monitor.isCanceled()) {
						throw CANCEL_EXCEPTION;
					}
				}
			}
		}

		// the site of this feature now becomes the TEMP directory
		// FIXME: make sure there is no other issue
		// like asking for stuff that hasn't been copied
		// or reusing this feature
		// of having an un-manageable temp site

		this.setSite(tempSite);

	}

	/**
	 */
	private void downloadDataLocally(IFeature targetFeature, INonPluginEntry[] dataToInstall, IProgressMonitor monitor) throws CoreException, IOException {

		URL sourceURL;
		// any other data
		INonPluginEntry[] entries = getNonPluginEntries();
		if (entries != null) {
			if (monitor != null) {
				monitor.beginTask("Installing Other Data information", dataToInstall.length);
				if (monitor.isCanceled()) {
					throw CANCEL_EXCEPTION;
				}
			}

			for (int j = 0; j < entries.length; j++) {
				String name = dataToInstall[j].getIdentifier();
				if (monitor != null) {
					monitor.subTask("..." + name);
				}

				// the id is URL format with "/"
				String dataEntryId = Site.DEFAULT_FEATURE_PATH + getIdentifier().toString() + "/" + name;
				// transform the id by asking the site to map them to real URL inside the SITE
				if (getSite() != null) {
					sourceURL = getSite().getSiteContentProvider().getArchivesReferences(dataEntryId);
					((Site) targetFeature.getSite()).storeFeatureInfo(getIdentifier(), name, sourceURL.openStream());
					if (monitor != null) {
						monitor.worked(1);
						if (monitor.isCanceled()) {
							throw CANCEL_EXCEPTION;
						}
					}
				}// getSite==null
			}
		}
	}
	
	
		/**
		 * Method install.
		 * @param targetFeature
		 * @param monitor
		 * @throws CoreException
		 */
	public void old_install(IFeature targetFeature, IProgressMonitor monitor) throws CoreException {

		IPluginEntry[] sourceFeaturePluginEntries = getPluginEntries();
		IPluginEntry[] targetSitePluginEntries = targetFeature.getSite().getPluginEntries();
		Site tempSite = (Site) SiteManager.getTempSite();

		// determine list of plugins to install
		// find the intersection between the two arrays of IPluginEntry...
		// The one teh site contains and teh one the feature contains
		IPluginEntry[] pluginsToInstall = intersection(sourceFeaturePluginEntries, targetSitePluginEntries);

		// private abstract - Determine list of content references id /archives id /bundles id that 
		// map the list of plugins to install
		String[] archiveIDToInstall = getContentReferenceToInstall(pluginsToInstall);

		try {
			// download and install data bundles
			// before we set the site of teh feature to the TEMP site
			INonPluginEntry[] dataEntries = getNonPluginEntries();
			if (dataEntries.length > 0) {
				downloadDataLocally(targetFeature, dataEntries, monitor);
			}

			// optmization, may be private to implementation
			// copy *blobs/content references/archives/bundles* in TEMP space
			if (((Site) getSite()).optimize()) {
				if (archiveIDToInstall != null) {
					downloadArchivesLocally(tempSite, archiveIDToInstall, monitor);
				}
			}

			// obtain the list of *Streamable Storage Unit*
			// from the archive
			if (monitor != null) {
				int total = pluginsToInstall == null ? 1 : pluginsToInstall.length + 1;
				monitor.beginTask("Install feature " + getLabel(), total);
			}
			if (pluginsToInstall != null) {
				InputStream inStream = null;
				for (int i = 0; i < pluginsToInstall.length; i++) {
					if (monitor != null) {
						monitor.subTask("Installing plug-in: " + pluginsToInstall[i]);
						if (monitor.isCanceled()) {
							throw CANCEL_EXCEPTION;
						}
					}

					open(pluginsToInstall[i]);
					String[] names = getStorageUnitNames(pluginsToInstall[i]);
					if (names != null) {
						for (int j = 0; j < names.length; j++) {
							if ((inStream = getInputStreamFor(pluginsToInstall[i], names[j])) != null)
								targetFeature.store(pluginsToInstall[i], names[j], inStream);
						}
					}
					close(pluginsToInstall[i]);
					if (monitor != null) {
						monitor.worked(1);
						if (monitor.isCanceled()) {
							throw CANCEL_EXCEPTION;
						}
					}

				}
			}

			// install the Feature info
			InputStream inStream = null;
			String[] names = getStorageUnitNames(this);
			if (names != null) {
				openFeature();
				if (monitor != null) {
					monitor.subTask("Installing Feature information");
					if (monitor.isCanceled()) {
						throw CANCEL_EXCEPTION;
					}
				}

				for (int j = 0; j < names.length; j++) {
					if ((inStream = getInputStreamFor(this, names[j])) != null)
						 ((Site) targetFeature.getSite()).storeFeatureInfo(getIdentifier(), names[j], inStream);
				}
				closeFeature();
				if (monitor != null) {
					monitor.worked(1);
					if (monitor.isCanceled()) {
						throw CANCEL_EXCEPTION;
					}
				}

			}

		} catch (IOException e) {
			String id = UpdateManagerPlugin.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status = new Status(IStatus.ERROR, id, IStatus.OK, "Error during Install", e);
			throw new CoreException(status);
		} finally {
			//do not clean up TEMP drive
			// as other feature may be there... clean up when exiting the plugin
		}
	}
	
	
		/**
	 * @see IPluginContainer#store(IPluginEntry, String, InputStream)
	 */
	public void store(IPluginEntry pluginEntry, String contentKey, InputStream inStream) throws CoreException {
		// check if pluginEntry already exists before passing to the site
		// anything else ?
		boolean found = false;
		int i = 0;
		IPluginEntry[] entries = getPluginEntries();
		while (i < entries.length && !found) {
			if (entries[i].equals(pluginEntry)) {
				found = true;
			}
			i++;
		}
		if (!found) {
			String id = UpdateManagerPlugin.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status = new Status(IStatus.ERROR, id, IStatus.OK, "The plugin:" + pluginEntry.getIdentifier().toString() + " is not part of the plugins of the feature:" + this.getIdentifier().toString(), null);
			throw new CoreException(status);
		}
		getSite().store(pluginEntry, contentKey, inStream);
	}
	
		/**
	 * perform pre processing before opening a plugin archive
	 * @param entry the plugin about to be opened
	 */
	protected void open(IPluginEntry entry) {
	};

	/**
	 * perform post processing to close a plugin archive
	 * @param entry the plugin about to be closed
	 */
	protected void close(IPluginEntry entry) throws IOException {
	};

	/**
	 * perform pre processing before opening the feature archive
	 */
	protected void openFeature() {
	};

	/**
	 * perform post processing to close a feature archive
	 */
	public void closeFeature() throws IOException {
	};
	
	
		/**
	 * return the list of FILE to be transfered for a Plugin
	 */
	protected abstract String[] getStorageUnitNames(IPluginEntry pluginEntry) throws CoreException;

	/**
	 * return the list of FILE to be transfered from within the Feature
	 */
	protected abstract String[] getStorageUnitNames(IFeature feature) throws CoreException;

	/**
	 * return the Stream of the FILE to be transfered for a Plugin
	 */
	protected abstract InputStream getInputStreamFor(IPluginEntry pluginEntry, String name) throws CoreException;

	/**
	 * return the Stream of FILE to be transfered from within the Feature
	 */
	protected abstract InputStream getInputStreamFor(IFeature feature, String name) throws IOException, CoreException;

	/**
	 * returns the list of archive to transfer/install
	 * in order to install the list of plugins
	 * 
	 * @param pluginsToInstall list of plugin to install 
	 */
	protected abstract String[] getContentReferenceToInstall(IPluginEntry[] pluginsToInstall);
	
	
		/**
	 * remove myself...
	 */
	public void old_remove(IProgressMonitor monitor) throws CoreException {

		// remove the feature and the plugins if they are not used and not activated

		// get the plugins from the feature
		IPluginEntry[] pluginsToRemove = ((SiteLocal) SiteManager.getLocalSite()).getDeltaPluginEntries(this);

		try {

			// obtain the list of *Streamable Storage Unit*
			// from the archive
			if (monitor != null) {
				int total = pluginsToRemove == null ? 1 : pluginsToRemove.length + 1;
				monitor.beginTask("Uninstall feature " + getLabel(), total);
			}
			if (pluginsToRemove != null) {
				for (int i = 0; i < pluginsToRemove.length; i++) {
					if (monitor != null) {
						monitor.subTask("Removing plug-in: " + pluginsToRemove[i]);
						if (monitor.isCanceled()) {
							throw CANCEL_EXCEPTION;
						}
					}

					remove(pluginsToRemove[i]);

					if (monitor != null) {
						monitor.worked(1);
						if (monitor.isCanceled()) {
							throw CANCEL_EXCEPTION;
						}
					}

				}
			}

			// remove the Feature info
			String[] names = getStorageUnitNames(this);
			if (names != null) {
				if (monitor != null) {
					monitor.subTask("Removing Feature information");
					if (monitor.isCanceled()) {
						throw CANCEL_EXCEPTION;
					}
				}

				((Site) this.getSite()).removeFeatureInfo(getIdentifier());

				closeFeature();
				if (monitor != null) {
					monitor.worked(1);
					if (monitor.isCanceled()) {
						throw CANCEL_EXCEPTION;
					}
				}

			}

		} catch (IOException e) {
			String id = UpdateManagerPlugin.getPlugin().getDescriptor().getUniqueIdentifier();
			IStatus status = new Status(IStatus.ERROR, id, IStatus.OK, "Error during Uninstall", e);
			throw new CoreException(status);
		}
	}
	
	System.getProperty("java.io.tmpdir")(java.lang.String) /tmp
	
