[sword-devel] c# sword bindings

Daniel Hughes trampster at gmail.com
Sat Apr 19 01:24:19 MST 2014


I have updated the binding to include strong naming of the assembly,
this is required for any third party to use the assembly, so is
essential. I have attached an updated patch.

On Wed, Apr 9, 2014 at 11:44 PM, Daniel Hughes <trampster at gmail.com> wrote:
> I think my copyright header was wrong so I've updated it. Attached is
> the new patch
>
> On Tue, Apr 8, 2014 at 5:36 PM, Daniel Hughes <trampster at gmail.com> wrote:
>> Bump....
>>
>> I realized that I sent this on April 1st, however I can assure you
>> it's not an April fools joke.
>>
>> Please let me know if I need to change anything in the patch.
>>
>> God bless,
>> Daniel Hughes
>>
>>
>>
>> On Tue, Apr 1, 2014 at 9:17 PM, Daniel Hughes <trampster at gmail.com> wrote:
>>> Attached is a patch which adds c# sword bindings.
>>>
>>> I'm not 100% sure of the correct way to submit it to sword. Please advise.
>>>
>>> God bless,
>>> Daniel Hughes
-------------- next part --------------
Index: bindings/CSharp/Sword/Manager.cs
===================================================================
--- bindings/CSharp/Sword/Manager.cs	(revision 0)
+++ bindings/CSharp/Sword/Manager.cs	(revision 0)
@@ -0,0 +1,162 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Sword
+{
+	public class Manager : IDisposable
+	{
+		IntPtr _handle;
+		
+		public Manager ()
+		{
+			_handle = NativeMethods.org_crosswire_sword_SWMgr_new();
+		}
+		
+		public Manager (string path)
+		{
+			_handle = NativeMethods.org_crosswire_sword_SWMgr_newWithPath(path);
+		}
+		
+		
+		internal IntPtr Handle
+		{
+			get
+			{
+				return _handle;	
+			}
+		}
+		
+		protected void Dispose(bool disposing)
+		{
+			if(disposing)
+			{
+				if(_handle != IntPtr.Zero)
+				{
+					NativeMethods.org_crosswire_sword_SWMgr_delete(_handle);
+					_handle = IntPtr.Zero;
+				}
+			}
+		}
+		
+		public Module GetModuleByName(string name)
+		{
+			IntPtr modulePtr = NativeMethods.org_crosswire_sword_SWMgr_getModuleByName(_handle, name);
+			if(modulePtr == IntPtr.Zero)
+			{
+				return null;	
+			}
+			return new Module(modulePtr);
+		}
+		
+		/// <summary>
+		/// Gets a list of the installed modules
+		/// </summary>
+		public IEnumerable<ModInfo> GetModInfoList()
+		{
+			IntPtr modulesPointer = NativeMethods.org_crosswire_sword_SWMgr_getModInfoList(_handle);
+			ModInfo modInfo = (ModInfo)Marshal.PtrToStructure(modulesPointer, typeof(ModInfo));
+			
+			while (modInfo.Name != null) 
+			{
+				yield return modInfo;
+				modulesPointer = new IntPtr(modulesPointer.ToInt64() + Marshal.SizeOf(typeof(ModInfo)));
+				modInfo = (ModInfo)Marshal.PtrToStructure(modulesPointer, typeof(ModInfo));
+			}
+		}
+		
+		public string Version
+		{
+			get
+			{
+				IntPtr versionPtr = NativeMethods.org_crosswire_sword_SWMgr_version(_handle);	
+				return Marshal.PtrToStringAnsi(versionPtr);
+			}
+		}
+		
+		public string PrefixPath
+		{
+			get
+			{
+				IntPtr prefixPathPtr = NativeMethods.org_crosswire_sword_SWMgr_getPrefixPath(_handle);	
+				return Marshal.PtrToStringAnsi(prefixPathPtr);
+			}
+		}
+		
+		public string ConfigPath
+		{
+			get
+			{
+				IntPtr configPathPtr = NativeMethods.org_crosswire_sword_SWMgr_getConfigPath(_handle);	
+				return Marshal.PtrToStringAnsi(configPathPtr);
+			}
+		}
+		
+		public void SetGlobalOption(string option, string @value)
+		{
+			NativeMethods.org_crosswire_sword_SWMgr_setGlobalOption(_handle, option, @value);
+		}
+		
+		public IEnumerable<string> GetGlobalOptionValues(string option)
+		{
+			IntPtr optionsPtr = NativeMethods.org_crosswire_sword_SWMgr_getGlobalOptionValues(_handle, option);
+			return NativeMethods.MarshalStringArray(optionsPtr);
+		}
+		
+		public void SetCipherKey(string modName, byte[] key)
+		{
+			NativeMethods.org_crosswire_sword_SWMgr_setCipherKey(_handle, modName, key);
+		}
+		
+		public bool Javascript
+		{
+			set
+			{
+				NativeMethods.org_crosswire_sword_SWMgr_setJavascript(_handle, value);
+			}
+		}
+		
+		public IEnumerable<string> AvailableLocales
+		{
+			get
+			{
+				IntPtr localesPtr = NativeMethods.org_crosswire_sword_SWMgr_getAvailableLocales(_handle);
+				return NativeMethods.MarshalStringArray(localesPtr);
+			}
+		}
+		
+		public string DefaultLocale
+		{
+			set
+			{
+				NativeMethods.org_crosswire_sword_SWMgr_setDefaultLocale(_handle, value);
+			}
+		}
+		
+		public string Translate(string text, string localeName)
+		{
+			IntPtr translatedPtr = NativeMethods.org_crosswire_sword_SWMgr_translate(_handle, text, localeName);
+			return Marshal.PtrToStringAnsi(translatedPtr);
+		}
+		
+		public void Dispose ()
+		{
+			Dispose (true);
+			GC.Collect();
+		}
+	}
+}
+
Index: bindings/CSharp/Sword/NativeMethods.cs
===================================================================
--- bindings/CSharp/Sword/NativeMethods.cs	(revision 0)
+++ bindings/CSharp/Sword/NativeMethods.cs	(revision 0)
@@ -0,0 +1,260 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Sword
+{
+	public enum SearchType 
+	{
+		REGEX = 1,
+		PHRASE = -1,
+		MULTIWORD = -2,
+		ENTRYATTR = -3,
+		LUCENE = -4
+	};
+	
+	[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
+	public struct ModInfo 
+	{
+		public string Name;
+		public string Description;
+		public string Category;
+		public string Language;
+	};
+	
+	[StructLayout(LayoutKind.Sequential)]
+	public struct SearchHit
+	{
+		IntPtr _modName;
+		IntPtr _key;
+		long Score;
+		
+		public bool IsNull()
+		{
+			return _key == IntPtr.Zero;
+		}
+		public string Key 
+		{ 
+			get 
+			{
+				if(_key == IntPtr.Zero)
+				{
+					return null;	
+				}
+				return Marshal.PtrToStringAnsi(_key); 
+			} 
+		}
+		
+		public string ModName 
+		{ 
+			get 
+			{ 
+				if(_modName == IntPtr.Zero)
+				{
+					return null;	
+				}
+				return Marshal.PtrToStringAnsi(_modName); 
+			} 
+		}
+	};
+	
+	public static class NativeMethods
+	{
+		
+		
+		public const string DLLNAME = "libsword.so";
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_new();
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_newWithPath(string path);
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_getModuleByName(IntPtr hSWMgr, string moduleName);
+		
+		[DllImport(DLLNAME)]
+		public static extern void org_crosswire_sword_SWModule_setKeyText(IntPtr hSWModule, string key);
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWModule_renderText(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getRawEntry(IntPtr hSWModule);
+
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getKeyText(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME)]
+		public static extern void org_crosswire_sword_SWMgr_delete(IntPtr hSWMgr);
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_getModInfoList(IntPtr hSWMgr);
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWModule_stripText(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME)]
+		public static extern void org_crosswire_sword_SWModule_setRawEntry(IntPtr hSWModule, string entryBuffer);
+		
+		[DllImport(DLLNAME)]
+		public static extern void org_crosswire_sword_SWModule_terminateSearch(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME)]
+		public static extern char org_crosswire_sword_SWModule_popError(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME)]
+		public static extern long org_crosswire_sword_SWModule_getEntrySize(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getEntryAttribute(IntPtr hSWModule, string level1, string level2, string level3, char filteredBool);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_parseKeyList(IntPtr hSWModule, string keyText);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_search(IntPtr hSWModule, string searchString, int searchType, long flags, string scope, IntPtr progressReporter);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern char org_crosswire_sword_SWModule_hasKeyChildren(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getKeyChildren(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getName(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getDescription(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getCategory(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getKeyParent(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWModule_previous(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWModule_next(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWModule_begin(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getRenderHeader(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWModule_getConfigEntry(IntPtr hSWModule, string key);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWModule_deleteSearchFramework(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern bool org_crosswire_sword_SWModule_hasSearchFramework(IntPtr hSWModule);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_version(IntPtr hSWMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_getPrefixPath(IntPtr hSWMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_getConfigPath(IntPtr hSWMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWMgr_setGlobalOption(IntPtr hSWMgr, string option, string val);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_getGlobalOptionValues(IntPtr hSWMgr, string option);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWMgr_setCipherKey(IntPtr hSWMgr, string modName, byte[] key);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWMgr_setJavascript(IntPtr hSWMgr, bool valueBool);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_getAvailableLocales(IntPtr hSWMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_SWMgr_setDefaultLocale(IntPtr hSWMgr, string name);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_SWMgr_translate(IntPtr hSWMgr, string text, string localeName);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_InstallMgr_reInit(IntPtr hInstallMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_InstallMgr_new(string baseDir, IntPtr statusReporter);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_InstallMgr_setUserDisclaimerConfirmed(IntPtr hInstallMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern int org_crosswire_sword_InstallMgr_syncConfig(IntPtr hInstallMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_InstallMgr_getRemoteSources(IntPtr hInstallMgr);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern IntPtr org_crosswire_sword_InstallMgr_getRemoteModInfoList(IntPtr hInstallMgr, IntPtr hSWMgr_deltaCompareTo, string sourceName);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern int org_crosswire_sword_InstallMgr_refreshRemoteSource(IntPtr hInstallMgr, string sourceName);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern int org_crosswire_sword_InstallMgr_remoteInstallModule(IntPtr hInstallMgr_from, IntPtr hSWMgr_to, string sourceName, string modName);
+		
+		[DllImport(DLLNAME, CallingConvention = CallingConvention.Cdecl)]
+		public static extern void org_crosswire_sword_InstallMgr_delete(IntPtr hInstallMgr);
+
+		public static IEnumerable<string> MarshalStringArray(IntPtr arrayPtr)
+		{
+			if(arrayPtr == IntPtr.Zero)
+			{
+				yield break;
+			}
+			
+			while(arrayPtr != IntPtr.Zero)
+			{
+				IntPtr ptr = Marshal.ReadIntPtr(arrayPtr);
+				if(ptr == IntPtr.Zero)
+				{
+					yield break;
+				}
+				string key = Marshal.PtrToStringAnsi(ptr);
+			 	yield return key;
+				arrayPtr = new IntPtr(arrayPtr.ToInt64() + IntPtr.Size);
+			}
+		}
+		
+		public static IEnumerable<ModInfo> MarshallModInfoArray(IntPtr pointer)
+		{
+			ModInfo modInfo = (ModInfo)Marshal.PtrToStructure(pointer, typeof(ModInfo));
+			
+			while (modInfo.Name != null) 
+			{
+				yield return modInfo;
+				pointer = new IntPtr(pointer.ToInt64() + Marshal.SizeOf(typeof(ModInfo)));
+				modInfo = (ModInfo)Marshal.PtrToStructure(pointer, typeof(ModInfo));
+			}	
+		}
+	}
+}
+
Index: bindings/CSharp/Sword/AssemblyInfo.cs
===================================================================
--- bindings/CSharp/Sword/AssemblyInfo.cs	(revision 0)
+++ bindings/CSharp/Sword/AssemblyInfo.cs	(revision 0)
@@ -0,0 +1,40 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Sword")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("daniel")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
Index: bindings/CSharp/Sword/InstallManager.cs
===================================================================
--- bindings/CSharp/Sword/InstallManager.cs	(revision 0)
+++ bindings/CSharp/Sword/InstallManager.cs	(revision 0)
@@ -0,0 +1,97 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+using System.Collections.Generic;
+
+namespace Sword
+{
+	public class InstallManager :  IDisposable
+	{
+		readonly IntPtr _handle;
+		
+		public InstallManager (string baseDirectory)
+		{
+			_handle = NativeMethods.org_crosswire_sword_InstallMgr_new(baseDirectory, IntPtr.Zero);
+		}
+		
+		public void SetUserDisclaimerConfirmed()
+		{
+			NativeMethods.org_crosswire_sword_InstallMgr_setUserDisclaimerConfirmed(_handle);	
+		}
+		
+		/// <summary>
+		/// Retrieves a list of sources from the master server.
+		/// </summary>
+		/// <returns>
+		/// True if successful
+		/// False if SetUserDisclaimerConfirmed has not been called.
+		/// False if the sync failed.
+		/// </returns>
+		public bool SyncConfig()
+		{
+			int result = NativeMethods.org_crosswire_sword_InstallMgr_syncConfig(_handle);
+			return result == 0 ? true : false;
+		}
+		
+		/// <summary>
+		/// Gets the remote sources.
+		/// You may need to call SyncConfig before calling this
+		/// to get an upto date source list.
+		/// </summary>
+		public IEnumerable<string> RemoteSources
+		{
+			get
+			{
+				IntPtr remoteSourcesPtr = NativeMethods.org_crosswire_sword_InstallMgr_getRemoteSources(_handle);
+				return NativeMethods.MarshalStringArray(remoteSourcesPtr);
+			}
+		}
+		
+		public bool RefreshRemoteSource(string sourceName)
+		{
+			int result = NativeMethods.org_crosswire_sword_InstallMgr_refreshRemoteSource(_handle, sourceName);
+			return result == 0 ? true : false;
+		}
+		
+		public IEnumerable<ModInfo> GetRemoteModInfoList(Manager manager, string sourceName)
+		{
+			IntPtr pointer = NativeMethods.org_crosswire_sword_InstallMgr_getRemoteModInfoList(_handle, manager.Handle, sourceName);
+			return NativeMethods.MarshallModInfoArray(pointer);
+		}
+		
+		public bool RemoteInstallModule(Manager to, string sourceName, string modName)
+		{
+			int result = NativeMethods.org_crosswire_sword_InstallMgr_remoteInstallModule(_handle, to.Handle, sourceName, modName);
+			return result == 0 ? true : false;
+		}
+		
+		protected void Dispose(bool disposing)
+		{
+			if(disposing)
+			{
+				if(_handle != IntPtr.Zero)
+				{
+					NativeMethods.org_crosswire_sword_InstallMgr_delete(_handle);
+				}
+			}
+		}
+		
+		public void Dispose ()
+		{
+			Dispose (true);
+			GC.Collect();
+		}
+	}
+}
+
Index: bindings/CSharp/Sword/Module.cs
===================================================================
--- bindings/CSharp/Sword/Module.cs	(revision 0)
+++ bindings/CSharp/Sword/Module.cs	(revision 0)
@@ -0,0 +1,214 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+using System.Runtime.InteropServices;
+using System.Collections.Generic;
+
+namespace Sword
+{
+	public class Module
+	{
+		IntPtr _handle;
+		
+		internal Module(IntPtr handle)
+		{
+			_handle = handle;
+		}
+		
+		public string Name
+		{
+			get
+			{
+				IntPtr namePtr = NativeMethods.org_crosswire_sword_SWModule_getName(_handle);
+				return Marshal.PtrToStringAnsi(namePtr);
+			}
+		}
+		
+		public string Description
+		{
+			get
+			{
+				IntPtr descriptionPtr = NativeMethods.org_crosswire_sword_SWModule_getDescription(_handle);
+				return Marshal.PtrToStringAnsi(descriptionPtr);
+			}
+		}
+		
+		public string Category
+		{
+			get
+			{
+				IntPtr categoryPtr = NativeMethods.org_crosswire_sword_SWModule_getCategory(_handle);
+				return Marshal.PtrToStringAnsi(categoryPtr);
+			}
+		}
+		
+		
+		/// <summary>
+		/// Special values handled for VerseKey modules:
+		///	[+-][book|chapter]	- [de|in]crement by chapter or book
+		///	(e.g.	"+chapter" will increment the VerseKey 1 chapter)
+		///	[=][key]		- position absolutely and don't normalize
+		///	(e.g.	"jn.1.0" for John Chapter 1 intro; "jn.0.0" For Book of John Intro)
+		/// </summary>
+		public string KeyText
+		{
+			get
+			{
+				IntPtr keyTextPtr = NativeMethods.org_crosswire_sword_SWModule_getKeyText(_handle);
+				return Marshal.PtrToStringAnsi(keyTextPtr);
+			}
+			set
+			{
+				NativeMethods.org_crosswire_sword_SWModule_setKeyText(_handle, value);
+			}
+		}
+		
+		public string Rendertext()
+		{
+			IntPtr keyTextPtr = NativeMethods.org_crosswire_sword_SWModule_renderText(_handle);
+			return Marshal.PtrToStringAnsi(keyTextPtr);
+		}
+		
+		public string RawEntry
+		{
+			get
+			{
+				IntPtr keyTextPtr = NativeMethods.org_crosswire_sword_SWModule_getRawEntry(_handle);
+				return Marshal.PtrToStringAnsi(keyTextPtr);
+			}
+			set
+			{
+				NativeMethods.org_crosswire_sword_SWModule_setRawEntry(_handle, value);
+			}
+		}
+		
+		public string StripText()
+		{
+			IntPtr keyTextPtr = NativeMethods.org_crosswire_sword_SWModule_stripText(_handle);
+			return Marshal.PtrToStringAnsi(keyTextPtr);
+		}
+		
+		public IEnumerable<SearchHit> Search(string searchString, SearchType searchType, long flags, string scope)
+		{
+			IntPtr searchHitPtr = NativeMethods.org_crosswire_sword_SWModule_search(_handle, searchString, (int)searchType, flags, scope, IntPtr.Zero);
+			SearchHit searchHit = (SearchHit)Marshal.PtrToStructure(searchHitPtr, typeof(SearchHit));
+			while (!searchHit.IsNull()) 
+			{
+				yield return searchHit;
+				searchHitPtr = new IntPtr(searchHitPtr.ToInt64() + Marshal.SizeOf(typeof(SearchHit)));
+				searchHit = (SearchHit)Marshal.PtrToStructure(searchHitPtr, typeof(SearchHit));
+			}
+		}
+		
+		public void TerminateSearch()
+		{
+			NativeMethods.org_crosswire_sword_SWModule_terminateSearch(_handle);	
+		}
+		
+		public char PopError()
+		{
+			return NativeMethods.org_crosswire_sword_SWModule_popError(_handle);	
+		}
+
+		public long EntrySize
+		{
+			get
+			{
+				return NativeMethods.org_crosswire_sword_SWModule_getEntrySize(_handle);	
+			}
+		}
+		
+		public IEnumerable<string> GetEntryAttribute(string level1, string level2, string level3, char filteredBool)
+		{
+			IntPtr attributePtrs = NativeMethods.org_crosswire_sword_SWModule_getEntryAttribute(_handle, level1, level2, level3, filteredBool);
+			return NativeMethods.MarshalStringArray(attributePtrs);
+		}
+		
+		public IEnumerable<string> ParseKeyList(string keyText)
+		{
+			IntPtr keyListPtrs = NativeMethods.org_crosswire_sword_SWModule_parseKeyList(_handle, keyText);
+			return NativeMethods.MarshalStringArray(keyListPtrs);
+		}
+		
+		public bool HasKeyChildren()
+		{
+			char hasChildren = NativeMethods.org_crosswire_sword_SWModule_hasKeyChildren(_handle);
+			return hasChildren == 1 ? true : false;
+		}
+
+		/// <summary>
+		/// This method returns child nodes for a genbook,
+		/// but has special handling if called on a VerseKey module:
+		/// [0..7] [testament, book, chapter, verse, chapterMax, verseMax, bookName, osisRef]
+		/// </summary>
+		public IEnumerable<string> KeyChildren
+		{
+			get
+			{
+				IntPtr childrenPtr = NativeMethods.org_crosswire_sword_SWModule_getKeyChildren(_handle);
+				return NativeMethods.MarshalStringArray(childrenPtr);
+			}
+		}
+		
+		public string KeyParent
+		{
+			get
+			{
+				IntPtr keyPtr = NativeMethods.org_crosswire_sword_SWModule_getKeyChildren(_handle);
+				return Marshal.PtrToStringAnsi(keyPtr);
+			}
+		}
+		
+		public void Prevous()
+		{
+			NativeMethods.org_crosswire_sword_SWModule_previous(_handle);
+		}
+		
+		public void Next()
+		{
+			NativeMethods.org_crosswire_sword_SWModule_next(_handle);
+		}
+		
+		public void Begin()
+		{
+			NativeMethods.org_crosswire_sword_SWModule_begin(_handle);
+		}
+		
+		public string RenderHeader
+		{
+			get
+			{
+				IntPtr headerPtr = NativeMethods.org_crosswire_sword_SWModule_getRenderHeader(_handle);
+				return Marshal.PtrToStringAnsi(headerPtr);
+			}
+		}
+		
+		public string GetConfigEntry(string key)
+		{
+			IntPtr entryPtr = NativeMethods.org_crosswire_sword_SWModule_getConfigEntry(_handle, key);
+			return Marshal.PtrToStringAnsi(entryPtr);
+		}
+		
+		public void DeleteSearchFramework()
+		{
+			NativeMethods.org_crosswire_sword_SWModule_deleteSearchFramework(_handle);	
+		}
+		
+		public bool HasSearchFramework()
+		{
+			return NativeMethods.org_crosswire_sword_SWModule_hasSearchFramework(_handle);
+		}
+	}
+}
+
Index: bindings/CSharp/Sword/Sword.csproj
===================================================================
--- bindings/CSharp/Sword/Sword.csproj	(revision 0)
+++ bindings/CSharp/Sword/Sword.csproj	(revision 0)
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{EFEE3557-86F2-4E46-AF7E-8BADEE240764}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>Sword</RootNamespace>
+    <AssemblyName>CSSword</AssemblyName>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>..\sword.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="NativeMethods.cs" />
+    <Compile Include="Module.cs" />
+    <Compile Include="Manager.cs" />
+    <Compile Include="InstallManager.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
Index: bindings/CSharp/Sword.Tests/InstallManagerTests.cs
===================================================================
--- bindings/CSharp/Sword.Tests/InstallManagerTests.cs	(revision 0)
+++ bindings/CSharp/Sword.Tests/InstallManagerTests.cs	(revision 0)
@@ -0,0 +1,132 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+using NUnit.Framework;
+using System.Linq;
+
+namespace Sword.Tests
+{
+	[TestFixture]
+	public class InstallManagerTests
+	{
+		InstallManager _installManager;
+		
+		[SetUp]
+		public void Setup()
+		{
+			_installManager = new InstallManager("baseDirectory");
+		}
+		
+		[TearDown]
+		public void TearDown()
+		{
+			_installManager.Dispose();
+		}
+		
+		[Test]
+		public void SetUserDisclaimerConfirmed_Called_DoesntCrash()
+		{
+			_installManager.SetUserDisclaimerConfirmed();
+		}
+		
+		[Test]
+		public void SyncConfig_UserDisclaimerConfirmed_ReturnsTrue()
+		{
+			//arrange
+			_installManager.SetUserDisclaimerConfirmed();
+			
+			//act
+			bool result = _installManager.SyncConfig();
+			
+			//assert
+			Assert.That (result, Is.True);
+		}
+		
+		[Test]
+		public void SyncConfig_UserDisclaimerNotConfirmed_ReturnsFalse()
+		{
+			//act
+			bool result = _installManager.SyncConfig();
+			
+			//assert
+			Assert.That (result, Is.False);
+		}
+		
+		[Test]
+		public void RemoteSources_Called_ReturnsRemoteSources()
+		{
+			//arrange
+			_installManager.SetUserDisclaimerConfirmed();
+			_installManager.SyncConfig();
+			
+			//act
+			var remoteSources = _installManager.RemoteSources.ToArray();
+			
+			//assert
+			Assert.That (remoteSources.Length > 0);
+		}
+		
+		[Test]
+		public void RefreshRemoteSource_Called_ReturnsTrue()
+		{
+			//arrange
+			_installManager.SetUserDisclaimerConfirmed();
+			_installManager.SyncConfig();
+			string firstSource =  _installManager.RemoteSources.First();
+			bool result = _installManager.RefreshRemoteSource(firstSource);
+			
+			//act
+			Assert.That (result, Is.True);
+		}
+		
+		[Test]
+		public void GetRemoteModInfoList_FirstSource_ReturnsModInfoList()
+		{
+			//arrange
+			_installManager.SetUserDisclaimerConfirmed();
+			_installManager.SyncConfig();
+			string firstSource =  _installManager.RemoteSources.First();
+			_installManager.RefreshRemoteSource(firstSource);
+			
+			ModInfo[] remoteModInfos;
+			using(Manager manager = new Manager())
+			{
+				//act
+				remoteModInfos = _installManager.GetRemoteModInfoList(manager, firstSource).ToArray();
+			}
+			
+			//assert
+			Assert.That (remoteModInfos.Length, Is.GreaterThan(0));
+		}
+		
+		[Test]
+		public void RemoteInstallModule_KJV_ReturnsTrue()
+		{
+			//arrange
+			_installManager.SetUserDisclaimerConfirmed();
+			Assert.That (_installManager.SyncConfig(), Is.True);
+			Assert.That (_installManager.RefreshRemoteSource("CrossWire"), Is.True);
+			
+			using(Manager manager = new Manager("LocalManager"))
+			{
+				//act
+				bool result = _installManager.RemoteInstallModule(manager, "CrossWire", "KJV");
+				
+				//assert
+				Assert.That (result, Is.True);
+			}
+		}
+	}
+}
+
Index: bindings/CSharp/Sword.Tests/ModuleTests.cs
===================================================================
--- bindings/CSharp/Sword.Tests/ModuleTests.cs	(revision 0)
+++ bindings/CSharp/Sword.Tests/ModuleTests.cs	(revision 0)
@@ -0,0 +1,162 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+using NUnit.Framework;
+using System.IO;
+
+namespace Sword.Tests
+{
+	[TestFixture]
+	public class ModuleTests
+	{
+		Module _swordModule;
+		Manager _swordManager;
+		
+		[TestFixtureSetUp]
+		public void Setup()
+		{
+			_swordManager = new Manager("LocalManager");
+			_swordModule = _swordManager.GetModuleByName("ESV");
+			
+			if(_swordModule != null)
+			{
+				return;	
+			}
+			using(var installManager = new InstallManager("baseDirectory"))
+			{
+				installManager.SetUserDisclaimerConfirmed();
+				installManager.SyncConfig();
+				installManager.RefreshRemoteSource("CrossWire");
+			
+				installManager.RemoteInstallModule(_swordManager, "CrossWire", "ESV");
+				_swordModule = _swordManager.GetModuleByName("ESV");
+			}
+		}
+		
+		[TestFixtureTearDown]
+		public void TearDown()
+		{
+			_swordManager.Dispose();
+		}
+		
+		[Test]
+		public void Name_Get_Esv()
+		{
+			//arrange
+			//act
+			string name =_swordModule.Name;
+			
+			//assert
+			Assert.That (name, Is.EqualTo ("ESV"));
+		}
+		
+		[Test]
+		public void Description_Get_DescriptionCorrect()
+		{
+			//arrange
+			//act
+			string description =_swordModule.Description;
+			
+			//assert
+			Assert.That (description, Is.EqualTo ("English Standard Version"));
+		}
+		
+		[Test]
+		public void Catagory_Get_CatagoryCorrect()
+		{
+			//arrange
+			//act
+			string catagory =_swordModule.Category;
+			
+			//assert
+			Assert.That (catagory, Is.EqualTo ("Biblical Texts"));
+		}
+		
+		[Test]
+		public void Previous_John3v16_John3v15()
+		{
+			//arrange
+			_swordModule.KeyText = "jn.3.16";
+			
+			//act
+			_swordModule.Prevous();
+			
+			//assert
+			Assert.That (_swordModule.KeyText, Is.EqualTo( "John 3:15"));
+		}
+		
+		[Test]
+		public void Next_John3v15_John3v16()
+		{
+			//arrange
+			_swordModule.KeyText = "jn.3.15";
+			
+			//act
+			_swordModule.Next();
+			
+			//assert
+			Assert.That (_swordModule.KeyText, Is.EqualTo( "John 3:16"));
+		}
+		
+		[Test]
+		public void Begin_John3v15_Genesis1v1()
+		{
+			//arrange
+			_swordModule.KeyText = "jn.3.15";
+			
+			//act
+			_swordModule.Begin();
+			
+			//assert
+			Assert.That (_swordModule.KeyText, Is.EqualTo( "Genesis 1:1"));
+		}
+		
+		[Test]
+		public void RenderHeader_John3v16_ReturnsNonNullOrEmpty()
+		{
+			//arrange
+			_swordModule.KeyText = "jn.3.16";
+			
+			//act
+			string header = _swordModule.RenderHeader;
+			
+			//assert
+			Assert.That (!string.IsNullOrEmpty(header));
+		}
+		
+		[Test]
+		public void RawEntry_Get_ContainsVerse()
+		{
+			//arrange
+			_swordModule.KeyText = "jn.3.16";
+
+			//act
+			string rawEntry = _swordModule.RawEntry;
+			
+			//assert
+			Assert.That (rawEntry.Contains ("God so loved"));
+		}
+		
+		public void HasSearchFramework_Doesnt_ReturnsFalse()
+		{
+			//arrange
+			//act
+			bool hasSearchFramework = _swordModule.HasSearchFramework();
+			
+			//assert
+			Assert.That (hasSearchFramework, Is.False);
+		}
+	}
+}
+
Index: bindings/CSharp/Sword.Tests/Sword.Tests.csproj
===================================================================
--- bindings/CSharp/Sword.Tests/Sword.Tests.csproj	(revision 0)
+++ bindings/CSharp/Sword.Tests/Sword.Tests.csproj	(revision 0)
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{72212684-1186-4F68-8FBD-BDBFDB8CC9BC}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Sword.Tests</RootNamespace>
+    <AssemblyName>CSSword.Tests</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <Commandlineparameters>ESV jn.3.16</Commandlineparameters>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>none</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="nunit.core, Version=2.5.10.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+      <Private>False</Private>
+      <Package>mono-nunit</Package>
+    </Reference>
+    <Reference Include="nunit.framework, Version=2.5.10.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77">
+      <Private>False</Private>
+      <Package>mono-nunit</Package>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyInfo.cs" />
+    <Compile Include="FlatApiLookup.cs" />
+    <Compile Include="ModuleTests.cs" />
+    <Compile Include="ManagerTests.cs" />
+    <Compile Include="InstallManagerTests.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Sword\Sword.csproj">
+      <Project>{EFEE3557-86F2-4E46-AF7E-8BADEE240764}</Project>
+      <Name>Sword</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
Index: bindings/CSharp/Sword.Tests/FlatApiLookup.cs
===================================================================
--- bindings/CSharp/Sword.Tests/FlatApiLookup.cs	(revision 0)
+++ bindings/CSharp/Sword.Tests/FlatApiLookup.cs	(revision 0)
@@ -0,0 +1,99 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+
+namespace Sword.Tests
+{
+	class FlatApiLookup
+	{
+		public static void Main (string[] args)
+		{	
+			using(var manager = new Manager())
+			{
+				var module = manager.GetModuleByName(args[0]);
+				
+				if (module == null) 
+				{
+					Console.Error.WriteLine("Could not find module {0}.  Available modules:", args[0]);
+					foreach(var modInfo in manager.GetModInfoList())
+					{
+						Console.WriteLine ("{0}\t - {1}", modInfo.Name, modInfo.Description);
+					}
+					return;
+				}
+				foreach(var locale in manager.AvailableLocales)
+				{
+					Console.WriteLine (locale);	
+				}
+			}
+		}
+		
+		public static void Search()
+		{
+			using(var manager = new Manager())
+			{
+				var module = manager.GetModuleByName("ESV");
+				
+				if (module == null) 
+				{
+					Console.Error.WriteLine("Could not find module {0}.  Available modules:", "ESV");
+					foreach(var modInfo in manager.GetModInfoList())
+					{
+						Console.WriteLine ("{0}\t - {1}", modInfo.Name, modInfo.Description);
+					}
+					return;
+				}
+				
+				foreach(var hit in module.Search("sin", SearchType.REGEX, 0, null))
+				{
+					Console.WriteLine(hit.Key); 
+				}
+				module.TerminateSearch();
+			}
+		}
+		
+		public static void ParseKeyList()
+		{
+			using(var manager = new Manager())
+			{
+				var module = manager.GetModuleByName("ESV");
+				
+				if (module == null) 
+				{
+					Console.Error.WriteLine("Could not find module {0}.  Available modules:", "ESV");
+					foreach(var modInfo in manager.GetModInfoList())
+					{
+						Console.WriteLine ("{0}\t - {1}", modInfo.Name, modInfo.Description);
+					}
+					return;
+				}
+				 
+				module.KeyText = "jn.3.16";
+				
+				Console.WriteLine("==Render=Entry============");
+				Console.WriteLine(module.KeyText);
+				Console.WriteLine("RenderText: " + module.Rendertext());
+				Console.WriteLine("StripText: " + module.StripText());
+				
+				Console.WriteLine("RawText: " + module.RawEntry);
+				Console.WriteLine("=========================="); 
+				
+				foreach(var key in module.ParseKeyList("James 1:19-30"))
+				{
+					Console.WriteLine (key);	
+				}
+			}
+		}
+	}
+}
\ No newline at end of file
Index: bindings/CSharp/Sword.Tests/AssemblyInfo.cs
===================================================================
--- bindings/CSharp/Sword.Tests/AssemblyInfo.cs	(revision 0)
+++ bindings/CSharp/Sword.Tests/AssemblyInfo.cs	(revision 0)
@@ -0,0 +1,40 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("Sword.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("daniel")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.*")]
+
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
Index: bindings/CSharp/Sword.Tests/ManagerTests.cs
===================================================================
--- bindings/CSharp/Sword.Tests/ManagerTests.cs	(revision 0)
+++ bindings/CSharp/Sword.Tests/ManagerTests.cs	(revision 0)
@@ -0,0 +1,111 @@
+// Copyright 2014  CrossWire Bible Society (http://www.crosswire.org)
+//  	CrossWire Bible Society
+//  	P. O. Box 2528
+//  	Tempe, AZ  85280-2528
+//  
+//  This program is free software; you can redistribute it and/or modify it
+//  under the terms of the GNU General Public License as published by the
+//  Free Software Foundation version 2.
+//  
+//  This program is distributed in the hope that it will be useful, but
+//  WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  General Public License for more details.
+using System;
+using NUnit.Framework;
+using System.IO;
+using System.Linq;
+
+namespace Sword.Tests
+{
+	[TestFixture]
+	public class ManagerTests
+	{
+		Manager _manager;
+		
+		[TestFixtureSetUp]
+		public void Setup()
+		{
+			_manager = new Manager();
+		}
+		
+		[TestFixtureTearDown]
+		public void TearDown()
+		{
+			_manager.Dispose();	
+		}
+		
+		[Test]
+		public void Version_Get_ReturnsAVersion()
+		{
+			//act
+			string swordVersion = _manager.Version;
+			
+			//assert
+			Version version;
+			Assert.That (Version.TryParse(swordVersion, out version));
+		}
+		
+		[Test]
+		public void PrefixPath_Get_ReturnsValidPath()
+		{
+			//act
+			string prefixPath = _manager.PrefixPath;
+			
+			//assert
+			Assert.That (Directory.Exists(prefixPath), Is.True);
+		}
+		
+		[Test]
+		public void ConfigPath_Get_ReturnsValidPath()
+		{
+			//act
+			string configPath = _manager.ConfigPath;
+			
+			//assert
+			Assert.That (Directory.Exists(configPath), Is.True);
+		}
+		
+		[Test]
+		public void SetCipherKey_Called_DoesntCrash()
+		{
+			//act
+			_manager.SetCipherKey("ESV", new byte[32]);
+		}
+		
+		[Test]
+		public void Javascript_Set_DoesntCrash()
+		{
+			//act
+			_manager.Javascript = true;
+		}
+		
+		[Test]
+		public void AvailableLocales_Get_DoesntCrash()
+		{
+			//act
+			var availableLocales = _manager.AvailableLocales.ToArray();
+			
+			//Assert
+			Assert.That (availableLocales[0].Contains("en"));
+		}
+		
+		[Test]
+		public void DefaultLocale_SetToEn_DoesntCrash()
+		{
+			//act
+			_manager.DefaultLocale = "en";
+		}
+		
+		[Test]
+		public void Translate_EnglishToEnglish_ReturnsOrginal()
+		{
+			//act
+			var result = _manager.Translate("love", "en");
+				
+			//assert
+			Assert.That (result, Is.EqualTo("love"));
+		}
+	}
+}
+
Index: bindings/CSharp/sword.snk
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: bindings/CSharp/sword.snk
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: bindings/CSharp/Sword.sln
===================================================================
--- bindings/CSharp/Sword.sln	(revision 0)
+++ bindings/CSharp/Sword.sln	(revision 0)
@@ -0,0 +1,33 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sword", "Sword\Sword.csproj", "{EFEE3557-86F2-4E46-AF7E-8BADEE240764}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sword.Tests", "Sword.Tests\Sword.Tests.csproj", "{72212684-1186-4F68-8FBD-BDBFDB8CC9BC}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{72212684-1186-4F68-8FBD-BDBFDB8CC9BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{72212684-1186-4F68-8FBD-BDBFDB8CC9BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{72212684-1186-4F68-8FBD-BDBFDB8CC9BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{72212684-1186-4F68-8FBD-BDBFDB8CC9BC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{EFEE3557-86F2-4E46-AF7E-8BADEE240764}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{EFEE3557-86F2-4E46-AF7E-8BADEE240764}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{EFEE3557-86F2-4E46-AF7E-8BADEE240764}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{EFEE3557-86F2-4E46-AF7E-8BADEE240764}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(MonoDevelopProperties) = preSolution
+		StartupItem = Sword\Sword.csproj
+		Policies = $0
+		$0.DotNetNamingPolicy = $1
+		$1.DirectoryNamespaceAssociation = None
+		$1.ResourceNamePolicy = FileFormatDefault
+		$0.StandardHeader = $2
+		$2.Text = @Copyright 2002-2014 CrossWire Bible Society (http://www.crosswire.org)\n \tCrossWire Bible Society\n \tP. O. Box 2528\n \tTempe, AZ  85280-2528\n \n This program is free software; you can redistribute it and/or modify it\n under the terms of the GNU General Public License as published by the\n Free Software Foundation version 2.\n \n This program is distributed in the hope that it will be useful, but\n WITHOUT ANY WARRANTY; without even the implied warranty of\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n General Public License for more details.
+		$2.IncludeInNewFiles = True
+	EndGlobalSection
+EndGlobal


More information about the sword-devel mailing list