gt: 				return new ByteArrayInputStream(s.getBytes("UTF-8"));
context: /*******************************************************************************
   * Copyright (c) 2009 Casey Marshall 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: 
   *    Casey Marshall - initial API and implementation
   *******************************************************************************/
  package ccw.wizards;
  
  import java.io.ByteArrayInputStream;
  import java.io.UnsupportedEncodingException;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  import org.eclipse.core.resources.IContainer;
  import org.eclipse.core.resources.IFile;
  import org.eclipse.core.resources.IProject;
  import org.eclipse.core.resources.IResource;
  import org.eclipse.core.resources.ResourcesPlugin;
  import org.eclipse.core.runtime.CoreException;
  import org.eclipse.core.runtime.IPath;
  import org.eclipse.jdt.core.IJavaProject;
  import org.eclipse.jdt.core.IPackageFragment;
  import org.eclipse.jdt.core.IPackageFragmentRoot;
  import org.eclipse.jdt.core.JavaCore;
  import org.eclipse.jdt.core.JavaModelException;
  import org.eclipse.jface.viewers.IStructuredSelection;
  import org.eclipse.jface.wizard.WizardPage;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Control;
  import org.eclipse.swt.widgets.Group;
  import org.eclipse.swt.widgets.Text;
  import org.eclipse.ui.INewWizard;
  import org.eclipse.ui.IWorkbench;
  import org.eclipse.ui.IWorkbenchPage;
  import org.eclipse.ui.IWorkbenchWindow;
  import org.eclipse.ui.editors.text.TextEditor;
  import org.eclipse.ui.ide.IDE;
  import org.eclipse.ui.wizards.newresource.BasicNewResourceWizard;
  
  import ccw.CCWPlugin;
  import ccw.ClojureCore;
  import ccw.util.ClojureInvoker;
  import ccw.util.CollectionUtils;
  import ccw.util.PlatformUtil;
  import ccw.util.StringUtils;
  
  public class NewClojureNamespaceWizard extends BasicNewResourceWizard implements INewWizard {
  
  	private final ClojureInvoker wizard = ClojureInvoker.newInvoker(
              CCWPlugin.getDefault(),
              "ccw.wizards.new-namespace");
  
  	
      public String kind() { return "Namespace"; }
  
      public String adjective() {
          return "";
      }
  
      protected String kind(boolean toLower) {
          if (toLower)
              return adjective().toLowerCase() + kind().toLowerCase();
          else
              return adjective() + kind();
      }
  
      class Page extends WizardPage {
          protected Page() {
              super("New Clojure " + kind());
          }
  
          IContainer javaSourceFolder;
          Text text;
          private String initialPackageName;
  
          public void createControl(Composite parent) {
              Composite topLevel = new Composite(parent, SWT.NONE);
              GridLayout topLayout = new GridLayout();
              topLayout.verticalSpacing = 0;
              topLevel.setLayout(topLayout);
  
              topLevel.setFont(parent.getFont());
  
              // Show description on opening
              setErrorMessage(null);
              setMessage(null);
              setControl(topLevel);
  
              boolean fail = false;
              if (getSelection().size() > 0) {
                  Object sel = getSelection().getFirstElement();
                  if (sel instanceof IPackageFragmentRoot) {
                  	javaSourceFolder = (IContainer) ((IPackageFragmentRoot)sel).getResource();
                  	initialPackageName = "";
                  } else if (sel instanceof IPackageFragment) {
                      javaSourceFolder = (IContainer) getPackageFragmentRoot((IPackageFragment)sel).getResource();
                      initialPackageName = ((IPackageFragment)sel).getElementName();
                  } else {
                  	IResource res = PlatformUtil.getAdapter(sel, IResource.class);
                  	if (res.getType() == IResource.FILE) {
                  		res = res.getParent();
                  	}
                      if (res.getProject() == null) {
                      	final String JAVA_SOURCE_ERROR = "Cannot create Clojure namespace outside a java source folder";
                          CCWPlugin.logError("Wrong selection type: " + sel.getClass() + ". " + JAVA_SOURCE_ERROR);
                          mainPage.setErrorMessage(JAVA_SOURCE_ERROR);
                          fail = true;
                      } else {
                      	IProject project = res.getProject();
                      	IJavaProject jproject = JavaCore.create(project);
                      	IPackageFragmentRoot[] roots;
  						try {
  							roots = jproject.getPackageFragmentRoots();
  							IPackageFragmentRoot firstSourceFragmentRoot = null;
  							for (IPackageFragmentRoot r: roots) {
  								if (r.getKind() == IPackageFragmentRoot.K_SOURCE) {
  									// Take the first sourceFolder in the list
  									if (firstSourceFragmentRoot == null) {
  										firstSourceFragmentRoot = r;
  									}
  									IContainer rc = (IContainer) r.getResource();
  									if (rc.getFullPath().isPrefixOf(res.getFullPath())) {
  										javaSourceFolder = rc;
  										initialPackageName = res.getFullPath().makeRelativeTo(rc.getFullPath()).toPortableString();
  										break;
  									}
  								}
  							}
  							if (javaSourceFolder == null) {
  								if (firstSourceFragmentRoot != null) {
  									// selected resource not in a package fragment root, take the first encountered
  									javaSourceFolder = (IContainer) firstSourceFragmentRoot.getResource();
  									initialPackageName = "";
  								}
  								mainPage.setErrorMessage("You must create a java source path before adding namespaces");
  								fail = true;
  							}
  						} catch (JavaModelException e) {
  							CCWPlugin.logError(e);
  							mainPage.setErrorMessage("Error while trying to find a java source folder to create the namespace into.");
  							fail = true;
  						}
                      }
                  }
                  
                  if (javaSourceFolder != null) {
                      setDescription("Create new Clojure " + kind(true)
                              + " in \"" + javaSourceFolder.getFullPath().toString()
                              + "\" of project \""
                              + javaSourceFolder.getProject().getName() + "\"");
                  }
              } else {
                  mainPage.setErrorMessage("Cannot determine in which project to create Clojure namespace.");
                  fail = true;
              }
  
              if (!fail) {
                  Group group = label(topLevel, kind() + " name:");
                  text = new Text(group, SWT.LEFT + SWT.BORDER);
                  String initText = ClojureCore.getNamespaceNameFromPackageName(initialPackageName);
                  if (!StringUtils.isBlank(initText)) {
                  	initText += ".";
                  }
                  text.setText(initText);
                  addToGroup(group, text);
                  text.setSelection(initText.length());
              }
          }
          
          private IPackageFragmentRoot getPackageFragmentRoot(IPackageFragment f) {
          	return (IPackageFragmentRoot) f.getAncestor(IPackageFragment.PACKAGE_FRAGMENT_ROOT);
          }
      }
  
      private Page mainPage;
  
      private Group label(Composite parent, String label) {
          Group group = new Group(parent, SWT.NONE);
          group.setText(label);
          GridLayout layout = new GridLayout();
          layout.numColumns = 2;
          group.setLayout(layout);
          group.setFont(parent.getFont());
          GridData gd = new GridData(GridData.FILL_HORIZONTAL);
          group.setLayoutData(gd);
          return group;
      }
  
      private void addToGroup(Group group, Control control) {
          GridData gd = new GridData(GridData.FILL_HORIZONTAL);
          control.setLayoutData(gd);
          control.setFont(group.getFont());
      }
  
      public NewClojureNamespaceWizard() {
          super();
      }
  
      /**
       * @see org.eclipse.jface.wizard.IWizard#addPages()
       */
      public void addPages() {
          super.addPages();
          mainPage = new Page();//$NON-NLS-1$
          mainPage.setTitle("New Clojure " + kind(false));
          mainPage.setDescription("Create new top-level Clojure " + kind(true));
          addPage(mainPage);
      }
  
      public void init(IWorkbench workbench, IStructuredSelection currentSelection) {
          super.init(workbench, currentSelection);
          setWindowTitle("New Clojure  " + kind(false));
          setNeedsProgressMonitor(false);
      }
  
      protected void initializeDefaultPageImageDescriptor() {
          super.initializeDefaultPageImageDescriptor();
      }
  
  	/**
  	 * @param parts
  	 *            the parts. This input is modified if extension is extracted
  	 * @return the extension
  	 */
  	private String extractExtension(List<String> parts) {
  		String extension;
  		final String lastPart = parts.get(parts.size() - 1);
  		if (wizard._("clojure-editor-extensions", lastPart) != null) {
  			extension = parts.remove(parts.size() - 1);
  		} else {
  			extension = "clj";
  		}
  		return extension;
  	}
  
      private String checkNamespaceSegment(String name) {
      	if (StringUtils.isBlank(name)) {
      		return "Empty namespace segment found";
      	}
          if (!Character.isJavaIdentifierStart(name.charAt(0))
          		&& !Character.isDigit(name.charAt(0)) // digits accepted
          		) {
              return "Invalid character \'" + name.charAt(0) + "\' at index " + 0
              		+ " for Clojure namespace file \'" + name + "'";
          }
          for (int i = 1; i < name.length(); i++) {
              if (!Character.isJavaIdentifierPart(name.charAt(i))) {
                  return "Invalid character \'"
                          + name.charAt(i)
                          + "\' at index "
                          + i
                          + " in namespace segment \'"
                          + name + "'";
              }
          }
      	return null;
      }
      
      private String checkNamespacename(List<String> parts) {
      	
      	if (parts.size() == 0) {
      		return "Empty namespace name";
      	}
      	
      	for (String part: parts) {
      		String msg = checkNamespaceSegment(part);
      		if (!StringUtils.isBlank(msg)) {
      			return msg;
      		}
      	}
      	return null;
      }
      
      private String mungePart(String p) {
      	return p.replaceAll("-", "_");  // FIXME should call clojure.core/munge
      }
      
      private List<String> mungeParts(List<String> l) {
      	List<String> ret = new ArrayList<String>(l.size());
      	for (String p: l) {
      		ret.add(mungePart(p));
      	}
      	return ret;
      }
  
      /**
       * @see org.eclipse.jface.wizard.IWizard#performFinish()
       */
      public boolean performFinish() {
      	final String userInput = mainPage.text.getText().trim();
      	
      	final List<String> unmungedParts = new ArrayList<String>(Arrays.asList(userInput.split("\\.")));
      	
      	final String extension = extractExtension(unmungedParts);
      	final String namespace = CollectionUtils.join(unmungedParts, ".");
      	
      	final List<String> parts = mungeParts(unmungedParts); 
  
          final String msg = checkNamespacename(parts);
          if (msg != null) {
          	mainPage.setErrorMessage(msg);
          	return false;
          }
          
          final IPath path = ccw.util.ResourceUtil.createPathFromList(parts).addFileExtension(extension);
          final IFile file = mainPage.javaSourceFolder.getFile(path);
  
          if (file.exists()) {
              mainPage.setErrorMessage("Namespace " + namespace + " already exists.");
              return false;
          }
  
          try {
          	final String content = content(namespace, extension);
          	ccw.util.ResourceUtil.createMissingParentFolders(file);
              file.create(stringToStream(content(namespace, extension), ResourcesPlugin.getEncoding()), true, null);
              IWorkbenchWindow dw = getWorkbench().getActiveWorkbenchWindow();
              if (dw != null) {
                  IWorkbenchPage page = dw.getActivePage();
                  if (page != null) {
                      TextEditor editor = (TextEditor) IDE.openEditor(page, file, true);
                      editor.selectAndReveal(content.length(), 0);
                  }
              }
          }
          catch (CoreException e) {
              CCWPlugin.logError(e);
              return false;
          }
  
          return true;
      }
      
      private ByteArrayInputStream stringToStream(String s, String encoding) {
      	try {
  			return new ByteArrayInputStream(s.getBytes(encoding));
  		} catch (UnsupportedEncodingException e) {
  			try {
  