Merge pull request #495 from nicolas-raoul/fix-for-issue2907-with-no-formatting-changes
[mono.git] / mcs / tools / monodoc / Monodoc / provider.cs
index c58f3d018522cc21ac32f03035a1b868e4419a97..180ae0d1f4eb2c6b158cba2780a5221680099aca 100644 (file)
@@ -5,6 +5,8 @@
 //   Miguel de Icaza (miguel@ximian.com)
 //
 // (C) 2002, Ximian, Inc.
+// Copyright 2003-2011 Novell
+// Copyright 2011 Xamarin Inc
 //
 // TODO:
 //   Each node should have a provider link
 //
 namespace Monodoc {
 using System;
+using System.Collections.Generic;
 using System.IO;
+using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Collections;
 using System.Diagnostics;
 using System.Configuration;
-using System.Text.RegularExpressions;
+using System.Reflection;
 using System.Xml;
 using System.Xml.XPath;
 using ICSharpCode.SharpZipLib.Zip;
 
-using Monodoc.Lucene.Net.Index;
-using Monodoc.Lucene.Net.Analysis.Standard;
+using Mono.Lucene.Net.Index;
+using Mono.Lucene.Net.Analysis.Standard;
+
+using Mono.Documentation;
+
 /// <summary>
 ///    This tree is populated by the documentation providers, or populated
 ///    from a binary encoding of the tree.  The format of the tree is designed
@@ -126,6 +133,8 @@ public class Node : IComparable {
        protected ArrayList nodes;
        protected internal int position;
 
+       static ArrayList empty = ArrayList.ReadOnly(new ArrayList(0));
+
        /// <summary>
        ///    Creates a node, called by the Tree.
        /// </summary>
@@ -173,7 +182,7 @@ public class Node : IComparable {
                get {
                        if (position < 0)
                                LoadNode ();
-                       return nodes;
+                       return nodes != null ? nodes : empty;
                }
        }
 
@@ -329,12 +338,12 @@ public class Node : IComparable {
        public static void PrintTree (Node node)
        {
                Indent ();
-               Console.WriteLine ("{0},{1}", node.Element, node.Caption);
-               if (node.Nodes == null)
+               Console.WriteLine ("{0},{1}\t[PublicUrl: {2}]", node.Element, node.Caption, node.PublicUrl);
+               if (node.Nodes.Count == 0)
                        return;
 
                indent++;
-               foreach (Node n in node.nodes)
+               foreach (Node n in node.Nodes)
                        PrintTree (n);
                indent--;
        }
@@ -345,6 +354,7 @@ public class Node : IComparable {
                        nodes.Sort ();
        }
 
+       [Obsolete("Use PublicUrl")]
        public string URL {
                get {
                        if (position < 0)
@@ -365,6 +375,14 @@ public class Node : IComparable {
                }
        }
 
+       public string PublicUrl {
+               get {
+                       return tree.HelpSource != null
+                               ? tree.HelpSource.GetPublicUrl (URL)
+                               : URL;
+               }
+       }
+
        int IComparable.CompareTo (object obj)
        {
                Node other = obj as Node;
@@ -376,13 +394,24 @@ public class Node : IComparable {
                if (other.position < 0)
                        other.LoadNode ();
 
-               Regex digits = new Regex (@"([\d]+)|([^\d]+)");
-               MatchEvaluator eval = delegate (Match m) {
-                       return (m.Value.Length > 0 && char.IsDigit (m.Value [0])) 
-                               ? m.Value.PadLeft (System.Math.Max (caption.Length, other.caption.Length)) 
-                               : m.Value;
-               };
-               return digits.Replace (caption, eval).CompareTo (digits.Replace (other.caption, eval));
+               var cap1 = caption;
+               var cap2 = other.caption;
+
+               /* Some node (notably from ecmaspec) have number prepended to them
+                * which we need to sort better by padding them to the same number
+                * of digits
+                */
+               if (char.IsDigit (cap1[0]) && char.IsDigit (cap2[0])) {
+                       int c1 = cap1.TakeWhile (char.IsDigit).Count ();
+                       int c2 = cap2.TakeWhile (char.IsDigit).Count ();
+
+                       if (c1 != c2) {
+                               cap1 = cap1.PadLeft (cap1.Length + Math.Max (0, c2 - c1), '0');
+                               cap2 = cap2.PadLeft (cap2.Length + Math.Max (0, c1 - c2), '0');
+                       }
+               }
+
+               return string.Compare (cap1, cap2, StringComparison.OrdinalIgnoreCase);
        }
 }
 
@@ -420,19 +449,30 @@ public class HelpSource {
 
        public static bool FullHtml = true;
 
+       // should only be enabled by ASP.NET webdoc
+       public static bool UseWebdocCache;
+
        //
        // The unique ID for this HelpSource.
        //
        int source_id;
        DateTime zipFileWriteTime;
        string name;
+       string basepath;
        TraceLevel trace_level = TraceLevel.Warning;
+       protected bool nozip;
+       protected string base_dir;
 
        public HelpSource (string base_filename, bool create)
        {
                this.name = Path.GetFileName (base_filename);
+               this.basepath = Path.GetDirectoryName (base_filename);
                tree_filename = base_filename + ".tree";
                zip_filename = base_filename + ".zip";
+               base_dir = XmlDocUtils.GetCacheDirectory (base_filename);
+               if (UseWebdocCache && !create && Directory.Exists (base_dir)) {
+                       nozip = true;
+               }
 
                if (create)
                        SetupForOutput ();
@@ -471,18 +511,38 @@ public class HelpSource {
                }
        }
 
+       /* This gives the full path of the source/ directory */
+       public string BaseFilePath {
+               get {
+                       return basepath;
+               }
+       }
+
        public TraceLevel TraceLevel {
                get { return trace_level; }
                set { trace_level = value; }
        }
+
+       public string BaseDir {
+               get {
+                       return base_dir;
+               }
+       }
        
        ZipFile zip_file;
        
        /// <summary>
        ///   Returns a stream from the packaged help source archive
        /// </summary>
-       public Stream GetHelpStream (string id)
+       public virtual Stream GetHelpStream (string id)
        {
+               if (nozip) {
+                       string path = XmlDocUtils.GetCachedFileName (base_dir, id);
+                       if (File.Exists (path))
+                               return File.OpenRead (path);
+                       return null;
+               }
+
                if (zip_file == null)
                        zip_file = new ZipFile (zip_filename);
 
@@ -505,27 +565,42 @@ public class HelpSource {
        
        public XmlReader GetHelpXml (string id)
        {
+               if (nozip) {
+                       Stream s = File.OpenRead (XmlDocUtils.GetCachedFileName (base_dir, id));
+                       string url = "monodoc:///" + SourceID + "@" + Uri.EscapeUriString (id) + "@";
+                       return new XmlTextReader (url, s);
+               }
+
                if (zip_file == null)
                        zip_file = new ZipFile (zip_filename);
 
                ZipEntry entry = zip_file.GetEntry (id);
                if (entry != null) {
                        Stream s = zip_file.GetInputStream (entry);
-                       string url = "monodoc:///" + SourceID + "@" + System.Web.HttpUtility.UrlEncode (id) + "@";
+                       string url = "monodoc:///" + SourceID + "@" + Uri.EscapeUriString (id) + "@";
                        return new XmlTextReader (url, s);
                }
                return null;
        }
        
-       public XmlDocument GetHelpXmlWithChanges (string id)
+       public virtual XmlDocument GetHelpXmlWithChanges (string id)
        {
+               if (nozip) {
+                       Stream s = File.OpenRead (XmlDocUtils.GetCachedFileName (base_dir, id));
+                       string url = "monodoc:///" + SourceID + "@" + Uri.EscapeUriString (id) + "@";
+                       XmlReader r = new XmlTextReader (url, s);
+                       XmlDocument ret = new XmlDocument ();
+                       ret.Load (r);
+                       return ret;
+               }
+
                if (zip_file == null)
                        zip_file = new ZipFile (zip_filename);
 
                ZipEntry entry = zip_file.GetEntry (id);
                if (entry != null) {
                        Stream s = zip_file.GetInputStream (entry);
-                       string url = "monodoc:///" + SourceID + "@" + System.Web.HttpUtility.UrlEncode (id) + "@";
+                       string url = "monodoc:///" + SourceID + "@" + Uri.EscapeUriString (id) + "@";
                        XmlReader r = new XmlTextReader (url, s);
                        XmlDocument ret = new XmlDocument ();
                        ret.Load (r);
@@ -666,6 +741,11 @@ public class HelpSource {
        {
                throw new NotImplementedException ();
        }
+
+       public virtual string GetPublicUrl (string id)
+       {
+               return id;
+       }
        
        public virtual string GetText (string url, out Node n)
        {
@@ -673,6 +753,16 @@ public class HelpSource {
                return null;
        }
 
+       protected string GetCachedText (string url)
+       {
+               if (!nozip)
+                       return null;
+               string file = XmlDocUtils.GetCachedFileName (base_dir, url);
+               if (!File.Exists (file))
+                       return null;
+               return File.OpenText (file).ReadToEnd ();
+       }
+
        public virtual Stream GetImage (string url)
        {
                return null;
@@ -722,7 +812,9 @@ public class HelpSource {
                System.Reflection.Assembly assembly = System.Reflection.Assembly.GetCallingAssembly ();
                Stream str_js = assembly.GetManifestResourceStream ("helper.js");
                StringBuilder sb = new StringBuilder ((new StreamReader (str_js)).ReadToEnd());
+               output.Write ("<script type=\"text/JavaScript\">\n");
                output.Write (sb.ToString ());
+               output.Write ("</script>\n");
                
                if (js != null) {
                        output.Write ("<script type=\"text/JavaScript\">\n");
@@ -787,37 +879,78 @@ public class RootTree : Tree {
        
        public static RootTree LoadTree ()
        {
-               string basedir;
-               string myPath = System.Reflection.Assembly.GetExecutingAssembly ().Location;
-               string cfgFile = myPath + ".config";
-               if (!File.Exists (cfgFile)) {
-                       basedir = ".";
-                       return LoadTree (basedir);
-               }
-               
-               XmlDocument d = new XmlDocument ();
-               d.Load (cfgFile);
-               basedir = d.SelectSingleNode ("config/path").Attributes ["docsPath"].Value;
-               
-               return LoadTree (basedir);
+               return LoadTree (null);
        }
+
+       const string MacMonoDocDir = "/Library/Frameworks/Mono.framework/Versions/Current/lib/monodoc";
        
        //
        // Loads the tree layout
        //
        public static RootTree LoadTree (string basedir)
        {
-               XmlDocument doc = new XmlDocument ();
+               if (basedir == null) {
+                       string myPath = System.Reflection.Assembly.GetExecutingAssembly ().Location;
+                       string cfgFile = myPath + ".config";
+                       if (!File.Exists (cfgFile)) {
+                               basedir = ".";
+                       }
+                       else {
+                               XmlDocument d = new XmlDocument ();
+                               d.Load (cfgFile);
+                               basedir = d.SelectSingleNode ("config/path").Attributes ["docsPath"].Value;
+                       }
+                       // Temporary workaround for developers distributing a monodoc.dll themselves on Mac
+                       if (Directory.Exists (MacMonoDocDir)){
+                               Console.WriteLine ("MacDir exists");
+                               if (!File.Exists (Path.Combine (basedir, "monodoc.xml"))){
+                                       basedir = MacMonoDocDir;
+                               }
+                       }
+               }
 
-               RootTree root = new RootTree ();
-               root.basedir = basedir;
-               
                //
                // Load the layout
                //
+               XmlDocument doc = new XmlDocument ();
                string layout = Path.Combine (basedir, "monodoc.xml");
                doc.Load (layout);
-               XmlNodeList nodes = doc.SelectNodes ("/node/node");
+
+               string osxExternalDir = "/Library/Frameworks/Mono.framework/External/monodoc";
+               string[] osxExternalSources = Directory.Exists (osxExternalDir)
+                       ? Directory.GetFiles (osxExternalDir, "*.source")
+                       : new string[0];
+
+               return LoadTree (basedir, doc, 
+                               Directory.GetFiles (Path.Combine (basedir, "sources"), "*.source")
+                               .Concat (osxExternalSources));
+       }
+
+       // Compatibility shim w/ Mono 2.6
+       public static RootTree LoadTree (string indexDir, XmlDocument docTree, IEnumerable sourceFiles)
+       {
+               return LoadTree (indexDir, docTree, sourceFiles.Cast<string>());
+       }
+
+       public static RootTree LoadTree (string indexDir, XmlDocument docTree, IEnumerable<string> sourceFiles)
+       {
+               if (docTree == null) {
+                       docTree = new XmlDocument ();
+                       using (var defTree = typeof(RootTree).Assembly.GetManifestResourceStream ("monodoc.xml"))
+                               docTree.Load (defTree);
+               }
+
+
+               sourceFiles = sourceFiles ?? new string [0];
+
+               //
+               // Load the layout
+               //
+
+               RootTree root = new RootTree ();
+               root.basedir = indexDir;
+
+               XmlNodeList nodes = docTree.SelectNodes ("/node/node");
 
                root.name_to_node ["root"] = root;
                root.name_to_node ["libraries"] = root;
@@ -832,73 +965,12 @@ public class RootTree : Tree {
                //
                // Load the sources
                //
-               string sources_dir = Path.Combine (basedir, "sources");
-               
-               string [] files = Directory.GetFiles (sources_dir);
-               foreach (string file in files){
-                       if (!file.EndsWith (".source"))
-                               continue;
-
-                       doc = new XmlDocument ();
-                       try {
-                               doc.Load (file);
-                       } catch {
-                               Console.Error.WriteLine ("Error: Could not load source file {0}", file);
-                               continue;
-                       }
-
-                       XmlNodeList extra_nodes = doc.SelectNodes ("/monodoc/node");
-                       if (extra_nodes.Count > 0)
-                               root.Populate (third_party, extra_nodes);
-
-                       XmlNodeList sources = doc.SelectNodes ("/monodoc/source");
-                       if (sources == null){
-                               Console.Error.WriteLine ("Error: No <source> section found in the {0} file", file);
-                               continue;
-                       }
-                       foreach (XmlNode source in sources){
-                               XmlAttribute a = source.Attributes ["provider"];
-                               if (a == null){
-                                       Console.Error.WriteLine ("Error: no provider in <source>");
-                                       continue;
-                               }
-                               string provider = a.InnerText;
-                               a = source.Attributes ["basefile"];
-                               if (a == null){
-                                       Console.Error.WriteLine ("Error: no basefile in <source>");
-                                       continue;
-                               }
-                               string basefile = a.InnerText;
-                               a = source.Attributes ["path"];
-                               if (a == null){
-                                       Console.Error.WriteLine ("Error: no path in <source>");
-                                       continue;
-                               }
-                               string path = a.InnerText;
-
-                               string basefilepath = Path.Combine (sources_dir, basefile);
-                               HelpSource hs = GetHelpSource (provider, basefilepath);
-                               if (hs == null)
-                                       continue;
-                               hs.RootTree = root;
-                               root.help_sources.Add (hs);
-                               root.name_to_hs [path] = hs;
-
-                               Node parent = root.LookupEntryPoint (path);
-                               if (parent == null){
-                                       Console.Error.WriteLine ("node `{0}' is not defined on the documentation map", path);
-                                       parent = third_party;
-                               }
-
-                               foreach (Node n in hs.Tree.Nodes){
-                                       parent.AddNode (n);
-                               }
-                               parent.Sort ();
-                       }
-               }
+               foreach (var sourceFile in sourceFiles)
+                       root.AddSourceFile (sourceFile);
                
                foreach (string path in UncompiledHelpSources) {
                        EcmaUncompiledHelpSource hs = new EcmaUncompiledHelpSource(path);
+                       hs.RootTree = root;
                        root.help_sources.Add (hs);
                        string epath = "extra-help-source-" + hs.Name;
                        Node hsn = root.CreateNode (hs.Name, "root:/" + epath);
@@ -916,6 +988,86 @@ public class RootTree : Tree {
 
                return root;
        }
+
+       public void AddSource (string sources_dir)
+       {
+               string [] files = Directory.GetFiles (sources_dir);
+
+               foreach (string file in files){
+                       if (!file.EndsWith (".source"))
+                               continue;
+                       AddSourceFile (file);
+               }
+       }
+
+       Dictionary<string,string> loadedSourceFiles = new Dictionary<string,string> ();
+       
+       public void AddSourceFile (string sourceFile)
+       {
+               if (loadedSourceFiles.ContainsKey (sourceFile))
+                       return;
+               
+               Node third_party = LookupEntryPoint ("various") ?? this;
+
+               XmlDocument doc = new XmlDocument ();
+               try {
+                       doc.Load (sourceFile);
+               }
+               catch {
+                       Console.Error.WriteLine ("Error: Could not load source file {0}", sourceFile);
+                       return;
+               }
+
+               XmlNodeList extra_nodes = doc.SelectNodes ("/monodoc/node");
+               if (extra_nodes.Count > 0)
+                       Populate (third_party, extra_nodes);
+
+               XmlNodeList sources = doc.SelectNodes ("/monodoc/source");
+               if (sources == null){
+                       Console.Error.WriteLine ("Error: No <source> section found in the {0} file", sourceFile);
+                       return;
+               }
+               loadedSourceFiles [sourceFile] = sourceFile;
+               foreach (XmlNode source in sources){
+                       XmlAttribute a = source.Attributes ["provider"];
+                       if (a == null){
+                               Console.Error.WriteLine ("Error: no provider in <source>");
+                               continue;
+                       }
+                       string provider = a.InnerText;
+                       a = source.Attributes ["basefile"];
+                       if (a == null){
+                               Console.Error.WriteLine ("Error: no basefile in <source>");
+                               continue;
+                       }
+                       string basefile = a.InnerText;
+                       a = source.Attributes ["path"];
+                       if (a == null){
+                               Console.Error.WriteLine ("Error: no path in <source>");
+                               continue;
+                       }
+                       string path = a.InnerText;
+
+                       string basefilepath = Path.Combine (Path.GetDirectoryName (sourceFile), basefile);
+                       HelpSource hs = GetHelpSource (provider, basefilepath);
+                       if (hs == null)
+                               continue;
+                       hs.RootTree = this;
+                       help_sources.Add (hs);
+                       name_to_hs [path] = hs;
+
+                       Node parent = LookupEntryPoint (path);
+                       if (parent == null){
+                               Console.Error.WriteLine ("node `{0}' is not defined on the documentation map", path);
+                               parent = third_party;
+                       }
+
+                       foreach (Node n in hs.Tree.Nodes){
+                               parent.AddNode (n);
+                       }
+                       parent.Sort ();
+               }
+       }
        
        // Delete nodes which does not have documentaiton (source)
        static bool PurgeNode(Node node)
@@ -948,9 +1100,21 @@ public class RootTree : Tree {
                
                return purge;
        }
-                                       
+
+       public static string[] GetSupportedFormats ()
+       {
+               return new string[]{
+                       "ecma", 
+                       "ecmaspec", 
+                       "error", 
+                       "hb", 
+                       "man", 
+                       "simple", 
+                       "xhtml"
+               };
+       }
        
-       static HelpSource GetHelpSource (string provider, string basefilepath)
+       public static HelpSource GetHelpSource (string provider, string basefilepath)
        {
                try {
                        switch (provider){
@@ -960,7 +1124,7 @@ public class RootTree : Tree {
                                return new EcmaUncompiledHelpSource (basefilepath);
                        case "monohb":
                                return new MonoHBHelpSource(basefilepath, false);
-                       case "xhtml":
+                       case "xhtml": case "hb":
                                return new XhtmlHelpSource (basefilepath, false);
                        case "man":
                                return new ManHelpSource (basefilepath, false);
@@ -983,7 +1147,33 @@ public class RootTree : Tree {
                        return null;
                }
        }
-               
+
+       public static Provider GetProvider (string provider, params string[] basefilepaths)
+       {
+               switch (provider) {
+               case "addins":
+                       return new AddinsProvider (basefilepaths [0]);
+               case "ecma": {
+                       EcmaProvider p = new EcmaProvider ();
+                       foreach (string d in basefilepaths)
+                               p.AddDirectory (d);
+                       return p;
+               }
+               case "ecmaspec":
+                       return new EcmaSpecProvider (basefilepaths [0]);
+               case "error":
+                       return new ErrorProvider (basefilepaths [0]);
+               case "man":
+                       return new ManProvider (basefilepaths);
+               case "simple":
+                       return new SimpleProvider (basefilepaths [0]);
+               case "xhtml":
+               case "hb":
+                       return new XhtmlProvider (basefilepaths [0]);
+               default:
+                       throw new NotSupportedException (provider);
+               }
+       }
 
        //
        // Maintains the name to node mapping
@@ -1043,7 +1233,7 @@ public class RootTree : Tree {
                        return lastHelpSourceTime;
                }
        }
-       
+
        public static bool GetNamespaceAndType (string url, out string ns, out string type)
        {
                int nsidx = -1;
@@ -1067,7 +1257,6 @@ public class RootTree : Tree {
                }
 
                if (nsidx == -1) {
-                       Console.Error.WriteLine ("Did not find dot in: " + url);
                        ns = null;
                        type = null;
                        return false;
@@ -1206,6 +1395,43 @@ public class RootTree : Tree {
                return (HelpSource) help_sources [id];
        }
        
+       //
+       // Fetches the node title
+       //
+       public string GetTitle (string url)
+       {
+               Node match_node;
+
+               if (url == null || url.StartsWith ("root:"))
+                       return "Mono Documentation";
+               
+               if (url.Length > 2 && url [1] == ':'){
+                       switch (url [0]){
+                       case 'N':
+                               return url.Substring (2) + " Namespace";
+
+                       case 'T':
+                               string s = TypeLookup (url, out match_node);
+                               if (match_node != null)
+                                       return match_node.Caption;
+                               return url.Substring (2) + " type";
+
+               case 'M':
+               case 'F':
+               case 'P':
+               case 'E':
+               case 'C':
+               case 'O':
+                       MemberLookup (url.Substring (0,2), url, out match_node);
+                       if (match_node != null)
+                               return match_node.Caption;
+                       break;
+                       }
+               }
+               
+               return "Mono Documentation";
+       }
+       
        string home_cache;
        /// <summary>
        ///    Allows every HelpSource to try to provide the content for this
@@ -1274,12 +1500,16 @@ public class RootTree : Tree {
                                sb.Replace ("@@FONT_FAMILY@@", SettingsHandler.Settings.preferred_font_family);
                                sb.Replace ("@@FONT_SIZE@@", SettingsHandler.Settings.preferred_font_size.ToString());
                                //contributions
+                               var visible = SettingsHandler.Settings.EnableEditing ? "block;" : "none;";
                                if ((oldContrib + contribs) == 0) {
                                        sb.Replace ("@@CONTRIB_DISP@@", "display: none;");
+                                        sb.Replace ("@@NO_CONTRIB_DISP@@", "display: " + visible);
                                } else {
+                                       sb.Replace ("@@CONTRIB_DISP@@", "display: " + visible);
                                        sb.Replace ("@@NO_CONTRIB_DISP@@", "display: none;");
                                        sb.Replace ("@@CONTRIBS@@", con.ToString ());
                                }
+                               sb.Replace ("@@EDITING_ENABLED@@", "display: " + visible);
                                        
                                // load the url of nodes
                                String add_str;
@@ -1398,7 +1628,11 @@ public class RootTree : Tree {
 
        public static void MakeIndex ()
        {
-               RootTree root = LoadTree ();
+               MakeIndex (LoadTree ());
+       }
+
+       public static void MakeIndex (RootTree root)
+       {
                if (root == null)
                        return;
 
@@ -1426,13 +1660,13 @@ public class RootTree : Tree {
                        // No octal in C#, how lame is that
                        chmod (path, 0x1a4);
                }
-               Console.WriteLine ("Documentation index updated");
+               Console.WriteLine ("Documentation index at {0} updated", path);
        }
 
        static bool IsUnix {
                get {
                        int p = (int) Environment.OSVersion.Platform;
-                       return ((p == 4) || (p == 128));
+                       return ((p == 4) || (p == 128) || (p == 6));
                 }
         }
 
@@ -1449,10 +1683,15 @@ public class RootTree : Tree {
        }
 
        public static void MakeSearchIndex ()
+       {
+               MakeSearchIndex (LoadTree ());
+       }
+
+       public static void MakeSearchIndex (RootTree root)
        {
                // Loads the RootTree
                Console.WriteLine ("Loading the monodoc tree...");
-               RootTree root = LoadTree ();
+
                if (root == null)
                        return;
 
@@ -1463,7 +1702,7 @@ public class RootTree : Tree {
                        if (!Directory.Exists (dir)) 
                                Directory.CreateDirectory (dir);
 
-                       writer = new IndexWriter(Lucene.Net.Store.FSDirectory.GetDirectory(dir, true), new StandardAnalyzer(), true);
+                       writer = new IndexWriter(Mono.Lucene.Net.Store.FSDirectory.GetDirectory(dir, true), new StandardAnalyzer(), true);
                } catch (UnauthorizedAccessException) {
                        //try in the .config directory
                        try {
@@ -1471,7 +1710,7 @@ public class RootTree : Tree {
                                if (!Directory.Exists (dir)) 
                                        Directory.CreateDirectory (dir);
 
-                               writer = new IndexWriter(Lucene.Net.Store.FSDirectory.GetDirectory(dir, true), new StandardAnalyzer(), true);
+                               writer = new IndexWriter(Mono.Lucene.Net.Store.FSDirectory.GetDirectory(dir, true), new StandardAnalyzer(), true);
                        } catch (UnauthorizedAccessException) {
                                Console.WriteLine ("You don't have permissions to write on " + dir);
                                return;