void setupDefaults() {
    python_interpreter = project_manager.findInterpreter(null);
    if (python_interpreter == null) PybaseMain.logE("No interpreter found");
    else PybaseMain.logD("Found interpreter " + python_interpreter.getName());

    File src = new File(base_directory, "src");
    if (src.isDirectory() || src.mkdir()) {
      File rsrc = new File("/src");
      IPathSpec ps = project_manager.createPathSpec(rsrc, true, true, true);
      project_paths.add(ps);
    }
  }
  void outputProject(boolean files, boolean paths, boolean clss, boolean opts, IvyXmlWriter xw) {
    if (xw == null) return;

    xw.begin("PROJECT");
    xw.field("NAME", project_name);
    xw.field("PATH", base_directory.getPath());
    xw.field("WORKSPACE", project_manager.getWorkSpaceDirectory().getPath());
    if (python_interpreter != null) {
      xw.textElement("EXE", python_interpreter.getExecutable().getPath());
    }

    if (paths) {
      for (IPathSpec ps : project_paths) {
        ps.outputXml(xw);
      }
    }
    if (files) {
      for (IFileSpec fs : project_files) {
        fs.outputXml(xw);
      }
    }

    if (opts) pybase_prefs.outputXml(xw, true);

    xw.end("PROJECT");
  }
  /** ***************************************************************************** */
  PybaseProject(PybaseMain pm, String name, File base) {
    pybase_main = pm;
    project_manager = pm.getProjectManager();
    base_directory = base.getAbsoluteFile();
    try {
      base_directory = base_directory.getCanonicalFile();
    } catch (IOException e) {
    }
    if (name == null) name = base.getName();
    project_name = name;
    project_paths = new ArrayList<IPathSpec>();
    project_files = new ArrayList<IFileSpec>();
    pybase_prefs = new PybasePreferences(pm.getSystemPreferences());
    all_files = new HashSet<IFileData>();
    parse_data = new HashMap<IFileData, ISemanticData>();

    File f = new File(base_directory, ".pybase");
    if (!f.exists()) f.mkdir();

    File f1 = new File(base_directory, ".pyproject");
    Element xml = IvyXml.loadXmlFromFile(f1);
    if (xml == null) {
      setupDefaults();
    } else {
      String bfile = IvyXml.getTextElement(xml, "EXE");
      File bf = (bfile == null ? null : new File(bfile));
      python_interpreter = project_manager.findInterpreter(bf);
      for (Element pe : IvyXml.children(xml, "PATH")) {
        IPathSpec ps = project_manager.createPathSpec(pe);
        project_paths.add(ps);
      }
      for (Element fe : IvyXml.children(xml, "FILE")) {
        IFileSpec fs = project_manager.createFileSpec(fe);
        project_files.add(fs);
      }
      pybase_prefs.loadXml(xml);
    }
    project_nature = new PybaseNature(pm, this);
    is_open = false;
    saveProject();
  }
  /** ***************************************************************************** */
  void editProject(Element pxml) {
    for (Element oelt : IvyXml.children(pxml, "OPTION")) {
      String k = IvyXml.getAttrString(oelt, "KEY");
      String v = IvyXml.getAttrString(oelt, "VALUE");
      pybase_prefs.setProperty(k, v);
    }

    Set<IPathSpec> done = new HashSet<IPathSpec>();
    boolean havepath = false;
    for (Element pelt : IvyXml.children(pxml, "PATH")) {
      havepath = true;
      File f1 = new File(IvyXml.getAttrString(pelt, "DIRECTORY"));
      try {
        f1 = f1.getCanonicalFile();
      } catch (IOException e) {
        f1 = f1.getAbsoluteFile();
      }
      boolean fnd = false;
      for (IPathSpec ps : project_paths) {
        if (done.contains(ps)) continue;
        File p1 = ps.getOSFile(base_directory);
        if (f1.equals(p1)) {
          done.add(ps);
          fnd = true;
          // handle changes to ps at this point
          break;
        }
      }
      if (!fnd) {
        String fp1 = f1.getPath();
        String fp2 = base_directory.getPath();
        boolean rel = false;
        if (fp1.startsWith(fp2)) {
          String fp3 = fp1.substring(fp2.length());
          StringTokenizer tok = new StringTokenizer(fp3, File.separator);
          File fd = null;
          while (tok.hasMoreTokens()) {
            String nm0 = tok.nextToken();
            if (fd == null) fd = new File(nm0);
            else fd = new File(fd, nm0);
          }
          f1 = fd;
          rel = true;
        }
        boolean usr = IvyXml.getAttrBool(pelt, "USER");
        IPathSpec ps = project_manager.createPathSpec(f1, usr, true, rel);
        done.add(ps);
        project_paths.add(ps);
      }
    }

    if (havepath) {
      for (Iterator<IPathSpec> it = project_paths.iterator(); it.hasNext(); ) {
        IPathSpec ps = it.next();
        if (!done.contains(ps)) it.remove();
      }
    }

    project_nature.rebuildPath();

    saveProject();
  }