Changeset 1231 for trunk/Documentation


Ignore:
Timestamp:
Mar 9, 2010, 11:31:00 AM (12 years ago)
Author:
Patrick Vacek
Message:

HowTo: First pass of revisions complete. Now starting another go to look for typos and other mistakes.

Location:
trunk/Documentation/Developer/PluginHowTo
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Documentation/Developer/PluginHowTo/HowToDeveloper.tex

    r1229 r1231  
    1616\usepackage{fix-cm}
    1717\usepackage{textcomp}
     18\usepackage[T1]{fontenc}
    1819
    1920
     
    172173
    173174\begin{itemize}
    174         \item .NET (a modern software framework with solutions to common programming problems from Microsoft)
     175        \item .NET (a modern software framework from Microsoft with solutions to common programming problems)
    175176        \item C\# (a modern object-oriented programming language, comparable to Java)
    176177    \item WPF (a modern purely vector-based graphical subsystem for rendering user interfaces in Windows-based applications)
     
    179180\end{itemize}
    180181
    181 This document is intended for plugin developers who want to contribute new visual or mathematical functionality to CT2. As of January 2010, the code consists of about 7000 lines of C\# code in the core system and about 240,641 lines of C\# code in 115 plugins.
     182This document is intended for plugin developers who want to contribute new visual or mathematical functionality to CT2. As of January 2010, the code consists of about 7000 lines of C\# code in the core system and about 250,000 lines of C\# code in 115 plugins.
    182183
    183184For further news and more screenshots please see the developer page \htmladdnormallink{http://www.cryptool2.vs.uni-due.de}{http://www.cryptool2.vs.uni-due.de}.
  • trunk/Documentation/Developer/PluginHowTo/part1.tex

    r1229 r1231  
    2626\clearpage
    2727
    28 \subsection*{The CrypTool2 SVN URL}
     28\subsection{The CrypTool2 SVN URL}
    2929\label{TheCrypTool2SVNURL}
    3030
     
    3333\url{https://www.cryptool.org/svn/CrypTool2/}
    3434
    35 To access the repository, you must provide a username and password. If you are a guest and just want to download our source code, you can use ``anonymous" as the username and an empty password. If you are a registered developer, just use your provided username and password (which should be the same as for the wiki).
     35To access the repository, you must provide a username and password. If you are a guest and just want to download our source code, you can use ``anonymous'' as the username and an empty password. If you are a registered developer, just use your provided username and password (which should be the same as for the wiki).
    3636
    37 \subsection*{Accessing the repository with TortoiseSVN}
     37\subsection{Accessing the repository with TortoiseSVN}
    3838\label{AccessingTheRepositoryWithTortoiseSVN}
    3939
     
    4343        \centering
    4444                \includegraphics[width=0.40\textwidth]{figures/tortoise_svn_checkout.jpg}
    45         \caption{Selecting ``SVN Checkout" from the context menu after installing TortoiseSVN.}
     45        \caption{Selecting ``SVN Checkout'' from the context menu after installing TortoiseSVN.}
    4646        \label{fig:tortoise_svn_checkout}
    4747\end{figure}
    4848
    49 First install TortoiseSVN (which unfortunately requires you to reboot your computer) and then create a directory (for instance ``CrypTool2") for storing the local working files somewhere on your computer. Right-click on this directory and select ``SVN Checkout" from the context menu. A window will appear in which you will be asked for the URL of the repository; use the address given above, as seen in Figure \ref{fig:tortoise_svn_checkout2}. The ``Checkout directory" should already be filled in correctly with your new folder. Then just hit ``OK", accept the certificate (if necessary), and enter your login information as described above. Mark the checkbox for saving your credentials if you don't want to enter them every time you work with the repository. Then hit ``OK", and now the whole CrypTool2 repository should be checked out into your chosen directory.
     49First install TortoiseSVN (which unfortunately requires you to reboot your computer) and then create a directory (for instance ``CrypTool2'') for storing the local working files somewhere on your computer. Right-click on this directory and select ``SVN Checkout'' from the context menu. A window will appear in which you will be asked for the URL of the repository; use the address given above, as seen in Figure \ref{fig:tortoise_svn_checkout2}. The ``Checkout directory'' should already be filled in correctly with your new folder. Then just hit ``OK'', accept the certificate (if necessary), and enter your login information as described above. Mark the checkbox for saving your credentials if you don't want to enter them every time you work with the repository. Then hit ``OK'', and now the whole CrypTool2 repository should be checked out into your chosen directory.
    5050\clearpage
    5151
     
    5757\end{figure}
    5858
    59 Later on, if changes have been made in the repository and you want to update your working copy, you can do this by right-clicking on any directory within the working files and choosing ``SVN Update" from the context menu. You should do this often to maintain a current version of the files.
     59Later on, if changes have been made in the repository and you want to update your working copy, you can do this by right-clicking on any directory within the working files and choosing ``SVN Update'' from the context menu. You should do this often to maintain a current version of the files.
    6060
    6161A TortoiseSVN tutorial can be found \href{http://www.mind.ilstu.edu/research/robots/iris4/developers/svntutorial}{here}.
    6262
    63 \subsection*{Committing your changes}
     63\subsection{Committing your changes}
    6464\label{CommitingYourChanges}
    6565
    66 If you are a registered developer, you can commit your file changes to the public CrypTool2 repository. Right-click on the directory within the working files that contains your changes and select ``SVN Commit" from the context menu to upload your changes. Please always provide \textit{meaningful descriptions} of your updates. You should commit your sources to our SVN repository as often as you can to ensure your interoperability with the rest of the project, but only commit code that successfully compiles and runs!
     66If you are a registered developer, you can commit your file changes to the public CrypTool2 repository. Right-click on the directory within the working files that contains your changes and select ``SVN Commit'' from the context menu to upload your changes. Please always provide \textit{meaningful descriptions} of your updates. You should commit your sources to our SVN repository as often as you can to ensure your interoperability with the rest of the project, but only commit code that successfully compiles and runs!
    6767
    6868\begin{figure}[h!]
    6969        \centering
    7070                \includegraphics[width=0.40\textwidth]{figures/tortoise_svn_commit.jpg}
    71         \caption{Selecting ``SVN Commit" from the context menu.}
     71        \caption{Selecting ``SVN Commit'' from the context menu.}
    7272        \label{fig:tortoise_svn_commit}
    7373\end{figure}
     
    111111This will close \#10 and \#12, and add a note to \#12.
    112112
    113 \subsection*{Ignore patterns}
     113\subsection{Ignore patterns}
    114114\label{IgnorePatterns}
    115115
     
    137137\label{CompilingTheSources}
    138138
    139 By this point you should have checked out a copy of the entire CrypTool repository. Compiling is pretty easy; just go to the \textit{trunk/} directory and open the \textbf{\textit{CrypTool 2.0.sln}} Visual Studio solution. The Visual Studio IDE should open with all the working plugins components nicely arranged. In case you are now starting Visual Studio for the first time, you will have to choose your settings. Just select either ``most common" or ``C\#" --- you can change this at any time later. On the right side is the project explorer, where you can see all the subprojects included in the solution. Look for the project \textbf{\textit{CrypWin.exe}} there. Once you have found it, right-click on it and select ``Set as StartUp-Project" from the context menu. Next, go to the menu bar and select ``Build" $\rightarrow$ ``Build Solution".
     139By this point you should have checked out a copy of the entire CrypTool repository. Compiling is pretty easy; just go to the \textit{trunk/} directory and open the \textbf{\textit{CrypTool 2.0.sln}} Visual Studio solution. The Visual Studio IDE should open with all the working plugins components nicely arranged. In case you are now starting Visual Studio for the first time, you will have to choose your settings. Just select either ``most common'' or ``C\#'' --- you can change this at any time later. On the right side is the project explorer, where you can see all the subprojects included in the solution. Look for the project \textbf{\textit{CrypWin.exe}} there. Once you have found it, right-click on it and select ``Set as StartUp-Project'' from the context menu. Next, go to the menu bar and select ``Build'' $\rightarrow$ ``Build Solution''.
    140140
    141 Then go to ``Debug" and select ``Start Debugging". CrypTool 2.0 should now start for the first time with your own compiled code. Presumably you have not changed anything yet, but you now have your own build of all the components (with the exception of CrypWin and AnotherEditor, since they are available only as binaries). If the program does not compile or start correctly, please consult our \href{https://www.cryptool.org/trac/CrypTool2/wiki/FAQ}{FAQ} and let us know if you found a bug.
     141Then go to ``Debug'' and select ``Start Debugging''. CrypTool 2.0 should now start for the first time with your own compiled code. Presumably you have not changed anything yet, but you now have your own build of all the components (with the exception of CrypWin and AnotherEditor, since they are available only as binaries). If the program does not compile or start correctly, please consult our \href{https://www.cryptool.org/trac/CrypTool2/wiki/FAQ}{FAQ} and let us know if you found a bug.
    142142
    143143If you are a \textbf{core developer}, hence somebody who can also compile CryWin and AnotherEditor, you should use the \textbf{\textit{CrypTool 2.0.sln}} solution from the \textit{trunk/CoreDeveloper/} directory (which will \textit{not} be visible to you if you are not a core developer). As a core developer, be aware that when you compile, you \textbf{change the \textit{CryWin.exe}} that is visible to everybody else. Thus, when doing a check-in, please make sure you \textit{really} want to check in a new binary. Core developers can also build a new setup and publish it as beta release on the website. This process is explained in the wiki at \url{https://www.cryptool.org/trac/CrypTool2/wiki/BuildSetup}.
  • trunk/Documentation/Developer/PluginHowTo/part2.tex

    r1229 r1231  
    66\label{sec:CreatingANewProject}
    77
    8 To begin, open Visual Studio, go to the menu bar and select ``File"~$\rightarrow$ ``New" $\rightarrow$ ``Project\ldots ". The following window will appear:
     8To begin, open Visual Studio, go to the menu bar and select ``File''~$\rightarrow$ ``New'' $\rightarrow$ ``Project\ldots ''. The following window will appear:
    99
    1010\begin{figure}[h!]
     
    1515\end{figure}
    1616
    17 \noindent If you are using Visual Studio 2008, select \textbf{``.NET-Framework 3.5"} as the target framework; the Express Edition will automatically choose the target framework. Then choose \textbf{``Class Library"} as the default template, as this will build the project for your plugin as a DLL file. Give the project a unique and meaningful name (such as ``Caesar" in our case), and choose a location to save it to. (The Express Edition will ask for a save location later when you close your project or environment). Select the subdirectory ``CrypPlugins" from your SVN trunk as the location. Finally, confirm by pressing the ``OK" button. Note that creating a new project in this manner also creates a new solution into which the project is placed.
     17\noindent If you are using Visual Studio 2008, select \textbf{``.NET-Framework 3.5''} as the target framework; the Express Edition will automatically choose the target framework. Then choose \textbf{``Class Library''} as the default template, as this will build the project for your plugin as a DLL file. Give the project a unique and meaningful name (such as ``Caesar'' in our case), and choose a location to save it to. (The Express Edition will ask for a save location later when you close your project or environment). Select the subdirectory ``CrypPlugins'' from your SVN trunk as the location. Finally, confirm by pressing the ``OK'' button. Note that creating a new project in this manner also creates a new solution into which the project is placed.
    1818
    1919\begin{figure}[h!]
    2020        \centering
    2121                \includegraphics[width=0.80\textwidth]{figures/save_solution_csharp_express.JPG}
    22         \caption{The Visual Studio C\# Express Edition ``Save Project" dialog window.}
     22        \caption{The Visual Studio C\# Express Edition ``Save Project'' dialog window.}
    2323        \label{fig:save_solution_csharp_express}
    2424\end{figure}
     
    4545\end{figure}
    4646
    47 \noindent Right-click in the Solution Explorer on the ``Reference" item and choose ``Add Reference". A window like the following should appear:
     47\noindent Right-click in the Solution Explorer on the ``Reference'' item and choose ``Add Reference''. A window like the following should appear:
    4848
    4949\begin{figure}[h!]
     
    5555\clearpage
    5656
    57 \noindent Unless you have created your new project in the same CrypTool 2.0 solution, you probably will not be able to select the library directly as seen above in Figure \ref{fig:add_pluginbase_source}; instead you can browse for the binary DLL as seen below in Figure \ref{fig:browse_reference}. Click on the ``Browse" tab and navigate to the folder in which you downloaded the CrypTool 2 project. Within that folder, go to \textit{\textbackslash CrypPluginBase\textbackslash bin\textbackslash Debug} and select the file ``CryptPluginBase.dll". The library reference can then be added by double clicking the file or pressing the ``OK" button.
     57\noindent Unless you have created your new project in the same CrypTool 2.0 solution, you probably will not be able to select the library directly as seen above in Figure \ref{fig:add_pluginbase_source}; instead you can browse for the binary DLL as seen below in Figure \ref{fig:browse_reference}. Click on the ``Browse'' tab and navigate to the folder in which you downloaded the CrypTool 2 project. Within that folder, go to \textit{\textbackslash CrypPluginBase\textbackslash bin\textbackslash Debug} and select the file ``CryptPluginBase.dll''. The library reference can then be added by double clicking the file or pressing the ``OK'' button.
    5858
    5959\begin{figure}[h!]
     
    6464\end{figure}
    6565
    66 \noindent Besides CrypPluginBase you will need to add three Windows assembly references to provide the necessary namespaces for the \textbf{user control} functions ``Presentation" and ``QuickWatchPresentation". This can be done in a similar manner as before with the ``CrypPluginBase" reference, but by selecting the ``.NET" tab and searching for the references there. Select the following .NET components:
     66\noindent Besides CrypPluginBase you will need to add three Windows assembly references to provide the necessary namespaces for the \textbf{user control} functions ``Presentation'' and ``QuickWatchPresentation''. This can be done in a similar manner as before with the ``CrypPluginBase'' reference, but by selecting the ``.NET'' tab and searching for the references there. Select the following .NET components:
    6767
    6868\begin{itemize}
     
    8686\label{sec:ModifyTheProjectProperties}
    8787
    88 It is important to make two small changes to your plugin's assembly data to make sure that it will be imported correctly into CrypTool 2. Go to the Solution Explorer and open ``AssemblyInfo.cs", which can be found in the ``Properties" folder. Make the following two changes:
     88It is important to make two small changes to your plugin's assembly data to make sure that it will be imported correctly into CrypTool 2. Go to the Solution Explorer and open ``AssemblyInfo.cs'', which can be found in the ``Properties'' folder. Make the following two changes:
    8989
    9090\begin{itemize}
    91         \item Change the attribute ``AssemblyVersion" to have the value ``2.0.*", and
    92         \item Comment out the attribute ``AssemblyFileVersion".
     91        \item Change the attribute ``AssemblyVersion'' to have the value ``2.0.*'', and
     92        \item Comment out the attribute ``AssemblyFileVersion''.
    9393\end{itemize}
    9494
     
    103103\label{sec:CreatingClassesForTheAlgorithmAndItsSettings}
    104104
    105 In the next step we will create two classes. The first class will be the main driver; we will call ours ``Caesar" since that is the name of the cipher that it will implement. In our case, this class has to inherit from IEncryption because it will be an ecryption plugin. If it was instead a hash plugin, this class should inherit from IHash. The second class will be used to store setting information for the plugin, and thus we will name ours ``CaesarSettings". It will need to inherit from ISettings.
     105In the next step we will create two classes. The first class will be the main driver; we will call ours ``Caesar'' since that is the name of the cipher that it will implement. In our case, this class has to inherit from IEncryption because it will be an encryption plugin. If it was instead a hash plugin, this class should inherit from IHash. The second class will be used to store setting information for the plugin, and thus we will name ours ``CaesarSettings''. It will need to inherit from ISettings.
    106106\clearpage
    107107
     
    109109\label{sec:CreatingAClassForTheAlgorithm}
    110110
    111 When starting a new project, Visual Studio automatically creates a class which has the name ``Class1.cs".  Since this is a rather non-descriptive name, we will change it. In our example, it should be ``Caesar.cs". There are two ways to change the name:
     111When starting a new project, Visual Studio automatically creates a class which has the name ``Class1.cs''.  Since this is a rather non-descriptive name, we will change it. In our example, it should be ``Caesar.cs''. There are two ways to change the name:
    112112
    113113\begin{itemize}
     
    117117%\clearpage
    118118
    119 \noindent Both options will achieve the same results. We will guide you through the second method. First, delete ``Class1.cs".
     119\noindent Both options will achieve the same results. We will guide you through the second method. First, delete ``Class1.cs''.
    120120
    121121\begin{figure}[h!]
     
    127127\clearpage
    128128
    129 \noindent Then right-click on the project item (in our case, ``Caesar") and select ``Add $\rightarrow$ Class\ldots ":
     129\noindent Then right-click on the project item (in our case, ``Caesar'') and select ``Add $\rightarrow$ Class\ldots '':
    130130
    131131\begin{figure}[h]
     
    137137\clearpage
    138138
    139 \noindent Finally, give your class a unique name. We will call our class ``Caesar.cs" and define it as public so that it will be available to other classes.
     139\noindent Finally, give your class a unique name. We will call our class ``Caesar.cs'' and define it as public so that it will be available to other classes.
    140140
    141141\begin{figure}[h!]
     
    151151\label{sec:CreatingASettingsClass}
    152152
    153 Add a second public class in the same way. We will call the class ``CaesarSettings". The settings class stores the necessary information about controls, captions, descriptions and default parameters (e.g.\ for key settings, alphabets, key length and type of action) to build the \textbf{TaskPane} in the CrypTool application.
     153Add a second public class in the same way. We will call the class ``CaesarSettings''. The settings class stores the necessary information about controls, captions, descriptions and default parameters (e.g.\ for key settings, alphabets, key length and type of action) to build the \textbf{TaskPane} in the CrypTool application.
    154154\clearpage
    155155
     
    167167\label{sec:AddingTheNamespacesAndInheritanceSourcesForTheCaesarClass}
    168168
    169 Open the ``Caesar.cs" file by double clicking on it in the Solution Explorer. To include the necessary namespaces in the class header, use the ``using" statement followed by the name of the desired namespace. The CrypTool 2.0 API provides the following namespaces:
     169Open the ``Caesar.cs'' file by double clicking on it in the Solution Explorer. To include the necessary namespaces in the class header, use the ``using'' statement followed by the name of the desired namespace. The CrypTool 2.0 API provides the following namespaces:
    170170
    171171\begin{itemize}
    172172        \item Cryptool.PluginBase --- contains interfaces such as IPlugin, IHash, and ISettings, as well as attributes, enumerations, delegates and extensions.
    173         \item Cryptool.PluginBase.Analysis --- contains interfaces for cryptanalysis plugins (such as ``Stream Comparator").
     173        \item Cryptool.PluginBase.Analysis --- contains interfaces for cryptanalysis plugins (such as ``Stream Comparator'').
    174174        \item Cryptool.PluginBase.Control --- contains global interfaces for the IControl feature for defining custom controls.
    175175        \item Cryptool.PluginBase.Cryptography --- contains interfaces for encryption and hash algorithms such as AES, DES and MD5.
     
    192192\end{itemize}
    193193
    194 \noindent It is important to define a new default namespace for our public class (``Caesar"). In CrypTool 2.0  the standard namespace convention is \textit{Cryptool.[name of class]}. Therefore our namespace will be defined as \textit{Cryptool.Caesar}.\clearpage
     194\noindent It is important to define a new default namespace for our public class (``Caesar''). In CrypTool 2.0  the standard namespace convention is \textit{Cryptool.[name of class]}. Therefore our namespace will be defined as \textit{Cryptool.Caesar}.\clearpage
    195195
    196196\noindent At this point, the source code should look like the following:
     
    215215
    216216\ \\ % ugly but functional
    217 \noindent Next we should let the ``Caesar" class inherit from IEncryption by making the following alteration:
     217\noindent Next we should let the ``Caesar'' class inherit from IEncryption by making the following alteration:
    218218
    219219\begin{lstlisting}
     
    229229\label{sec:AddingInterfaceFunctionsToTheCaesarClass}
    230230
    231 You may notice an underscore underneath the ``I" in ``IEncryption". Move your mouse over it, or place the cursor on it and press ``Shift+Alt+F10" and the following submenu should appear:
     231You may notice an underscore underneath the ``I'' in ``IEncryption''. Move your mouse over it, or place the cursor on it and press ``Shift+Alt+F10'' and the following submenu should appear:
    232232
    233233\begin{figure}[h!]
    234234        \centering
    235235                \includegraphics{figures/inherit_submenu.jpg}
    236         \caption{Inherit submenu}
     236        \caption{An inheritance submenu.}
    237237        \label{fig:inherit_submenu}
    238238\end{figure}
    239239
    240 Select the item ``Implement interface `IEncryption'". Visual Studio will automatically generate all the interface members necessary for interaction with the CrypTool 2 core. (This step will save you a lot of typing!)
     240Select the item ``Implement interface `IEncryption'\,''. Visual Studio will automatically generate all the interface members necessary for interaction with the CrypTool 2 core. (This step will save you a lot of typing!)
    241241\clearpage
    242242
     
    328328\label{sec:AddingTheNamespaceAndInterfacesToTheCaesarSettingsClass}
    329329
    330 Let's now take a look at the second class in our example, ``CaesarSettings", by double-clicking on the ``CaesarSettings.cs" file in the Solution Explorer. First, we need to again include the ``Cryptool.PluginBase" namespace to the class header. Then we must let the settings class inherit from ``ISettings" in the same manner as was done with the Caesar class. Visual Studio will again automatically generate code from the CrypTool interface as seen below. (We can again remove the lines \texttt{using System;} and \texttt{using System.Linq;}, as we do not need those references.)\\
     330Let's now take a look at the second class in our example, ``CaesarSettings'', by double-clicking on the ``CaesarSettings.cs'' file in the Solution Explorer. First, we need to again include the ``Cryptool.PluginBase'' namespace to the class header. Then we must let the settings class inherit from ``ISettings'' in the same manner as was done with the Caesar class. Visual Studio will again automatically generate code from the CrypTool interface as seen below. (We can again remove the lines \texttt{using System;} and \texttt{using System.Linq;}, as we do not need those references.)\\
    331331
    332332\begin{lstlisting}
     
    368368\label{sec:AddingControlsToTheCaesarSettingsClass}
    369369
    370 The settings class is used to populate the TaskPane in the CrypTool 2 application so that the user can modify settings at will. To meet these ends we will need to implement some controls such as buttons and text boxes. If you will be implementing an algorithm that does not have any user-defined settings (e.g. a hash function), then this class can be left empty; you will, however, still have to modify the ``HasChanges" property to avoid a ``NotImplementedException". The following code demonstrates the modifications necessary to create the backend for the TaskPane for our Caesar algorithm. You can also look at the source code of other algorithms in the subversion repository for examples of how to create the TaskPane backend.\\
     370The settings class is used to populate the TaskPane in the CrypTool 2 application so that the user can modify settings at will. To meet these ends we will need to implement some controls such as buttons and text boxes. If you will be implementing an algorithm that does not have any user-defined settings (e.g. a hash function), then this class can be left empty; you will, however, still have to modify the ``HasChanges'' property to avoid a ``NotImplementedException''. The following code demonstrates the modifications necessary to create the backend for the TaskPane for our Caesar algorithm. You can also look at the source code of other algorithms in the subversion repository for examples of how to create the TaskPane backend.\\
    371371
    372372\begin{lstlisting}
     
    735735For testing purposes you can just create a simple black and white PNG image with MS Paint or Paint.NET. The proper image size is 40x40 pixels, but since the image will be rescaled if necessary, any size is technically acceptable.
    736736
    737 Once you have saved your icon, you should add it directly to the project or to a subdirectory. In the project solution, we created a new folder named ``Images". This can be done by right-clicking on the project item (``Caesar" in our example) and selecting ``Add $\rightarrow$ New Folder". The icon can be added to this folder (or to the project directly, or to any other subdirectory) by right-clicking on the folder and selecting ``Add $\rightarrow$ Existing Item".
     737Once you have saved your icon, you should add it directly to the project or to a subdirectory. In the project solution, we created a new folder named ``Images''. This can be done by right-clicking on the project item (``Caesar'' in our example) and selecting ``Add $\rightarrow$ New Folder''. The icon can be added to this folder (or to the project directly, or to any other subdirectory) by right-clicking on the folder and selecting ``Add $\rightarrow$ Existing Item''.
    738738
    739739\begin{figure}[h!]
     
    745745\clearpage
    746746
    747 A new window will then appear. Select ``Image Files" as the file type and select your newly-created icon for your plugin.
     747A new window will then appear. Select ``Image Files'' as the file type and select your newly-created icon for your plugin.
    748748
    749749\begin{figure}[h!]
     
    755755\clearpage
    756756
    757 Finally, we must set the icon as a ``Resource" to avoid including the icon as a separate file. Right-click on the icon and select ``Properties" as seen below.
     757Finally, we must set the icon as a ``Resource'' to avoid including the icon as a separate file. Right-click on the icon and select ``Properties'' as seen below.
    758758
    759759\begin{figure}[h!]
     
    764764\end{figure}
    765765
    766 In the ``Properties" panel, set the ``Build Action" to ``Resource".
     766In the ``Properties'' panel, set the ``Build Action'' to ``Resource''.
    767767
    768768\begin{figure}[h!]
     
    777777\label{sec:DefiningTheAttributesOfTheCaesarClass}
    778778
    779 Now let's go back to the code of the Caesar class (the ``Caesar.cs" file in our example). The first thing we will do is define the attributes of our class. These attributes are used to provide additional information for the CrypTool 2.0 environment. If they are not properly defined, your plugin won't show up in the application display, even if everything else is implemented correctly.
     779Now let's go back to the code of the Caesar class (the ``Caesar.cs'' file in our example). The first thing we will do is define the attributes of our class. These attributes are used to provide additional information for the CrypTool 2.0 environment. If they are not properly defined, your plugin won't show up in the application display, even if everything else is implemented correctly.
    780780
    781781Attributes are used for \textbf{declarative} programming and provide metadata that can be added to the existing .NET metadata. CrypTool provides a set of custom attributes that are used to mark the different parts of your plugin.
    782782
    783 These attributes can be defined anywhere within the ``Cryptool.Caesar" namespace, but customarily they are defined right before the class declaration.
    784 
    785 \subsubsection*{The \textit{[Author]} attribute}
     783These attributes can be defined anywhere within the ``Cryptool.Caesar'' namespace, but customarily they are defined right before the class declaration.
     784
     785\subsection{The \textit{[Author]} attribute}
    786786\label{sec:TheAuthorAttribute}
    787787
     
    795795\end{figure}
    796796
    797 As can be see above, the author attribute takes four elements of type string. These elements are:
     797As can be seen above, the author attribute takes four elements of type string. These elements are:
    798798
    799799\begin{itemize}
     
    815815%\end{figure}
    816816
    817 \subsubsection*{The \textit{[PluginInfo]} attribute}
     817\subsection{The \textit{[PluginInfo]} attribute}
    818818\label{sec:ThePluginInfoAttribute}
    819819
     
    827827\end{figure}
    828828
    829 This attribute has the following parameters:
     829\noindent This attribute has the following parameters:
    830830
    831831\begin{itemize}
     
    838838\end{itemize}
    839839
    840 Unused elements should be set to null or an empty string.
     840\noindent Unused elements should be set to null or an empty string.
    841841
    842842(There are a few limitations and bugs that still exist in the \textit{[PluginInfo]} attribute that will be resolved in a future version. Firstly, it is possible to use the plugin without setting a caption, although this is not recommended. In the future the plugin will fail to load without a caption. Secondly, a zero-length toolTip string currently causes the toolTip to appear as an empty box in the application. Lastly, the toolTip and description do not currently support internationalization and localization.)
    843843
    844 In our example the first parameter called ''resourceFile'' has to be set to ''Cryptool.Caesar.Resource.res'' because we want to provide the plugin multilingual and want to store the labels and caption in a resource file. Otherwise ignore this element.
     844In our example, the ``resourceFile'' parameter should be set to ``Cryptool.Caesar.Resource.res''. This file will be used to store the label and caption text to support multilingualism.
     845
     846%\begin{figure}[h]
     847%       \centering
     848%               \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_resourceFile.JPG}
     849%       \caption{Attribute PluginInfo element resourceFile}
     850%       \label{fig:attribute_plugininfo_resourceFile}
     851%\end{figure}
     852
     853The second parameter, ``startable'' should be set to ``false'', because our encryption algorithm is not an input generator plugin.
     854
     855%\begin{figure}[h!]
     856%       \centering
     857%               \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_startable.jpg}
     858%       \caption{Attribute PluginInfo startable}
     859%       \label{fig:attribute_plugininfo_startable}
     860%\end{figure}
     861
     862The next two parameters are necessary to define the plugin's name and description. Since we are using a resource file, we should place here the names of the resource fields that contain the description and caption.  (We call also just write simple text strings instead of using outsourced references.)
     863
     864%\begin{figure}[h!]
     865%       \centering
     866%               \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_description.jpg}
     867%       \caption{Attribute PluginInfo name and description}
     868%       \label{fig:attribute_plugininfo_description}
     869%\end{figure}
     870
     871The next element defines the location path of the description file. The parameter is composed in the format \textit{$<$assembly name$>$/$<$file name$>$} or, if you want to store your description files in a separate folder (as in our case), \textit{$<$assembly name$>$/$<$path$>$/$<$file name$>$}. The description file must be an XAML file. In our case, we shall create a folder named ``DetailedDescription'' in which to store our XAML file with any necessary images. Our folder structure looks as follows:
     872
     873\begin{figure}[h!]
     874        \centering
     875                \includegraphics[width=.30\textwidth]{figures/attribute_plugininfo_detailed_descr_path.jpg}
     876        \caption{The folder structure as seen in the Solution Explorer.}
     877        \label{fig:attribute_plugininfo_icon_path}
     878\end{figure}
     879
     880%Accordingly the attribute parameter has to be set to:
     881%\begin{figure}[h!]
     882%       \centering
     883%               \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_detailed_descr.jpg}
     884%       \caption{Attribute PluginInfo description file}
     885%       \label{fig:attribute_plugininfo_icon}
     886%\end{figure}
     887
     888Once a detailed description has been written in the XAML file, it can be accessed in the CrypTool 2 application by right-clicking on the plugin icon in the workspace and selecting ``Show description''.
     889
     890\begin{figure}[h!]
     891        \centering
     892                \includegraphics[width=1.00\textwidth]{figures/xaml_description.jpg}
     893        \caption{A detailed description provided through an XAML file.}
     894        \label{fig:xaml_description}
     895\end{figure}
     896\clearpage
     897
     898The last parameter tells CrypTool 2 the names of the provided icons. This parameter is an array composed of strings in the format \textit{$<$assembly name$>$/$<$file name$>$} or \textit{$<$assembly name$>$/$<$path$>$/$<$file name$>$}.
     899
     900The first and most important icon is the plugin icon, which will be shown in CrypTool 2 in the ribbon bar and navigation pane. Once the icon has been added to the project as described in Section \ref{sec:AddingAnIconToTheCaesarClass}, we must accordingly tell CrypTool 2 where to find the icon. This can be seen above in Figure \ref{fig:attribute_plugininfo}.
     901
     902%\begin{figure}[h!]
     903%       \centering
     904%               \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_icons.jpg}
     905%       \caption{Attribute PluginInfo icons}
     906%       \label{fig:attribute_plugininfo_icons}
     907%\end{figure}
     908
     909If your plugin will use additional icons, you should define the paths to each of them by adding the path strings to the \textit{[PluginInfo]} attribute parameter list, each separated by a comma. We have added two further icons for the context menu in the CrypTool 2 workspace. (If you do choose to add more icons, don't forget to add the icons to your solution.)
     910
     911\subsection{The \textit{[EncryptionType]} attribute}
     912\label{sec:TheEncryptionTypeAttribute}
     913
     914The third and last attribute, \textit{[EncryptionType]}, is needed to tell CrypTool 2 what type of plugin we are creating. CrypTool 2 uses this information to place the plugin in the correct group in the navigation pane and ribbon bar. In our example, since Caesar is a classical algorithm, we will define the follows:
     915
    845916\begin{figure}[h]
    846917        \centering
    847                 \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_resourceFile.JPG}
    848         \caption{Attribute PluginInfo element resourceFile}
    849         \label{fig:attribute_plugininfo_resourceFile}
    850 \end{figure}
    851 
    852 The second parameter called ''startable'' has to be set to ''false'', because our encryption algorithm is neither an input nor generator plugin.
    853 \begin{figure}[h!]
    854         \centering
    855                 \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_startable.jpg}
    856         \caption{Attribute PluginInfo startable}
    857         \label{fig:attribute_plugininfo_startable}
    858 \end{figure}
    859 
    860 The next two parameters are needed to define the plugin's name and its description. Now that we decided to provide a resource file we have to place here the both resource field names which contains the description and captions. Otherwise just write here a simple string text:
    861 \begin{figure}[h!]
    862         \centering
    863                 \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_description.jpg}
    864         \caption{Attribute PluginInfo name and description}
    865         \label{fig:attribute_plugininfo_description}
    866 \end{figure}
    867 
    868 The next element defines the location path of the description file. The parameter is made up by $<$Assembly name$>$/$<$filename$>$ or $<$Assembly name$>$/$<$Path$>$/$<$file name$>$ if you want to store your description files in a separate folder (as seen on the icon). The description file has to be of type XAML. In our case we create a folder called ''DetailedDescription'' and store our XAML file there with the necessary images if needed. How you manage the files and folders is up to you. This folder could now look as you can see below:
    869 \begin{figure}[h!]
    870         \centering
    871                 \includegraphics{figures/attribute_plugininfo_detailed_descr_path.jpg}
    872         \caption{Attribute PluginInfo icon and description file path}
    873         \label{fig:attribute_plugininfo_icon_path}
    874 \end{figure}
    875 
    876 Accordingly the attribute parameter has to be set to:
    877 \begin{figure}[h!]
    878         \centering
    879                 \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_detailed_descr.jpg}
    880         \caption{Attribute PluginInfo description file}
    881         \label{fig:attribute_plugininfo_icon}
    882 \end{figure}
    883 
    884 The detailed description could now look like this in CrypTool (right click plugin icon on workspace and select ''Show description''):\clearpage
    885 \begin{figure}[h!]
    886         \centering
    887                 \includegraphics[width=1.00\textwidth]{figures/xaml_description.jpg}
    888         \caption{XAML detailed description}
    889         \label{fig:xaml_description}
    890 \end{figure}
    891 
    892 The last parameter tells CrypTool the names of the provided icons. This parameter is made up by $<$Assembly name$>$/$<$file name$>$ or $<$Assembly name$>$/$<$Path$>$/$<$file name$>$.\\\\
    893 The most important icon is the plugin icon, which will be shown in CrypTool in the ribbon bar or navigation pane (This is the first icon in list, so you have to provide at least one icon for a plugin). As named above how to add an icon to the solution accordingly we have to tell CrypTool where to find the icon by setting this parameter as you can see below:
    894 \begin{figure}[h!]
    895         \centering
    896                 \includegraphics[width=1.00\textwidth]{figures/attribute_plugininfo_icons.jpg}
    897         \caption{Attribute PluginInfo icons}
    898         \label{fig:attribute_plugininfo_icons}
    899 \end{figure}
    900 
    901 You can define further icon paths if needed, by adding the path string separated by a comma. We just add here two further icons (don't forget to add the icons to your solution) to provide them for the context menu in the CrypTool workspace.\\\\
    902 \textit{[EncryptionType]}\\
    903 The third and last attribute called ''EncryptionType'' is needed to tell CrypTool which type of plugin we want to provide. CrypTool is now able to place the plugin in the right group at the navigation pane or/and ribbon bar. Therefore Caesar is a classical algorithm so we have to set the following attribute:
    904 \begin{figure}[h]
    905         \centering
    906                 \includegraphics[width=1.00\textwidth]{figures/attribute_encryption_type.JPG}
    907         \caption{Attribute encryption type}
     918                \includegraphics[width=.90\textwidth]{figures/attribute_encryptiontype_new.jpg}
     919        \caption{A fully-defined \textit{[EncryptionType]} attribute.}
    908920        \label{fig:attribute_encryption_type}
    909921\end{figure}
    910922
    911 The ''EncryptionType'' attribute can also be set as the following types:
     923The possible values of the \textit{[EncryptionType]} attribute are as follows:
     924
    912925\begin{itemize}
    913         \item Asymmetric = for asymmetric encryption algorithms like RSA
    914         \item Classic = for classic encryption or hash algorithms like Caesar or MD5
    915         \item Hybrid = for a combination of several algorithm where the data is encrypted symmetric and the encryption key asymmetric
    916         \item SymmetricBlock = for all block cipher algorithms like DES, AES or Twofish
    917         \item SymmetricStream = for all stream cipher algorithms like RC4, Rabbit or SEAL
     926        \item Asymmetric --- for asymmetrical encryption algorithms, such as RSA.
     927        \item Classic --- for classical encryption or hash algorithms, such as Caesar or MD5.
     928        \item Hybrid --- for algorithms which are actually a combination of several algorithms, such as algorithms in which the data is encrypted symmetrically and the encryption key asymmetrically.
     929        \item SymmetricBlock --- for block cipher algorithms, such as DES, AES and Twofish.
     930        \item SymmetricStream --- for stream cipher algorithms like RC4, Rabbit and SEAL.
    918931\end{itemize}
    919932
    920 
    921 \section{Set the private variables for the settings in the class Caesar}\label{sec:SetThePrivateVariablesForTheSettingsInTheClassCaesar}
    922 The next step is to define some private variables needed for the settings, input and output data which could look like this:
     933\section{Defining the private variables of the settings in the Caesar class}
     934\label{sec:DefiningThePrivateVariablesOfTheSettingsInTheCaesarClass}
     935
     936The next step is to define some private variables that are needed for the settings, input, and output data. In our example, this will look like the following:
     937
    923938\begin{lstlisting}
    924939public class Caesar : IEncryption
     
    932947        #endregion
    933948\end{lstlisting}
    934 Please notice if there is a sinuous line at the code you type for example at the ''CryptoolStream'' type of the variable listCryptoolStreamsOut. ''CryptoolStream'' is a data type for input and output between plugins and is able to handle large data amounts. To use the CrypTool own stream type, include the namespace ''Cryptool.PluginBase.IO'' with a ''using'' statement as explained in chapter \ref{sec:CaesarNamespacesAndInheritance}. Check the other code entries while typing and update the missing namespaces.\\
    935 The following private variables are being used in this example:
     949
     950\ \\ % ugly but functional
     951If your algorithm works with longs strings of code, it is recommended to use the ``CryptoolStream'' data type. This was designed for input and output between plugins and to handle large amounts of data. To use the native CrypTool stream type, include the namespace ``Cryptool.PluginBase.IO'' with a ``using'' statement as explained in section \ref{sec:AddingTheNamespacesAndInheritanceSourcesForTheCaesarClass}.
     952
     953The following private variables will be used in our example:
     954
    936955\begin{itemize}
    937         \item CaesarSettings settings: required to implement the IPlugin interface properly
    938         \item string inputString: sting to read the input data from
    939         \item string outputString: string to save the output data
    940         \item enum CaesarMode: our own definition how to select between an encryption or decryption. It's up to you how to solve your algorithm
    941         \item List$<$CryptoolStream$>$ listCryptoolStreamsOut: list of all streams being created by Caesar plugin, required to perform a clean dispose
     956        \item CaesarSettings settings --- required to implement the IPlugin interface properly.
     957        \item string inputString --- string from which to read the input data.
     958        \item string outputString --- string to which to save the output data.
     959        \item enum CaesarMode --- used to select either encryption or decryption.
     960        \item List$<$CryptoolStream$>$ listCryptoolStreamsOut --- a list of all streams created by the plugin, which helps to perform a clean dispose.
    942961\end{itemize}
    943 \section{Define the code of the class Caesar to fit the interface}\label{sec:DefineTheCodeOfTheClassCaesarToFitTheInterface}
    944 Next we have to complete our code to correctly serve the interface.\\
    945 First we add a constructor to our class where we can create an instance of our settings class and a function to handle events:
     962
     963\section{Implementing the interfaces in the Caesar class}
     964\label{sec:ImplementingTheInterfacesInTheCaesarClass}
     965
     966The next major step is to write out our implementations of the interfaces. First we will add a constructor to our class. We will use this to create an instance of our settings class and a function to handle events:
     967
    946968\begin{lstlisting}
    947969public class Caesar : IEncryption
     
    961983        }
    962984\end{lstlisting}
    963 Secondly, we have to implement the property ''Settings'' defined in the interface:
     985
     986\ \\
     987\indent Secondly, we must implement the ``Settings'' property declared in the interface. An outline of this property should have been automatically generated by implementing the interface (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}); just edit it appropriately to communicate with your settings class as we have done here:
     988
    964989\begin{lstlisting}
    965990public ISettings Settings
     
    969994}
    970995\end{lstlisting}
    971 Thirdly we have to define five properties with their according attributes. This step is necessary to tell CrypTool that these properties are input/output properties used for data exchange with other plugins or to provide our plugin with external data.\\
    972 The attribute is named ''PropertyInfo'' and consists of the following elements:
     996
     997\ \\
     998\indent Thirdly, we must define five properties, each with an appropriate attribute. This step is necessary to tell CrypTool 2 if the properties are used for input our output and to provide the plugin with external data.
     999
     1000The attribute that we will use for each proprerty is called \textit{[PropertyInfo]} and it consists of the following elements:
     1001
    9731002\begin{itemize}
    974         \item direction = defines whether this property is an input or output property, i.e. whether it reads input data or writes output data
     1003        \item direction --- defines whether this property is an input or output property, i.e., whether it reads input data or writes output data. The possible values are:
    9751004        \begin{itemize}
    9761005                \item Direction.Input
    9771006                \item Direction.Output
    9781007        \end{itemize}
    979         \item caption = caption of the property (e.g. shown at the input on the dropped icon in the editor), see below:
     1008        \item caption --- the caption for the property displayed over the input of the icon after it has been placed in the editor), as seen below:
     1009       
    9801010\begin{figure}[h]
    9811011        \centering
    982                 \includegraphics{figures/property_caption.jpg}
    983         \caption{Possible property caption}
     1012                \includegraphics[width=.55\textwidth]{figures/property_caption.jpg}
     1013        \caption{A possible property caption and toolTip.}
    9841014        \label{fig:property_caption}
    9851015\end{figure}
    986         \item toolTip = tooltip of the property (e.g. shown at the input arrow on the dropped icon in the editor), see above
    987         \item descriptionUrl = not used right now
    988         \item mandatory = this flag defines whether an input is required to be connected by the user. If set to true, there has to be an input connection that provides data. If no input data is provided for mandatory input, your plugin will not be executed in the workflow chain. If set to false, connecting the input is optional. This only applies to input properties. If using Direction.Output, this flag is ignored.
    989         \item hasDefaultValue = if this flag is set to true, CrypTool treats this plugin as though the input has already input data.
    990         \item DisplayLevel = define in which display levels your property will be shown in CrypTool. CrypTool provides the following display levels:
     1016
     1017        \item toolTip --- the toolTip for the property displayed over the input arrow of the icon after it has been placed in the editor, as seen above.
     1018        \item descriptionUrl --- currently not used; fill it with null or an empty string.
     1019        \item mandatory --- this flag determines whether an input must be attached by the user to use the plugin. If set to true, an input connection will be required or else the plugin will not be executed in the workflow chain. If set to false, connecting an input is optional. As this only applies to input properties, if the direction has been set to ``output'', this flag will be ignored.
     1020        \item hasDefaultValue --- if this flag is set to true, CrypTool 2 will assume that the property has a default input value that does not require user input.
     1021        \item displayLevel --- determines in which display levels your property will be shown in CrypTool 2. These are used to hide more advanced item from less-experienced users; a Beginner will not see the properties marked as any other level, but a Professional will have access to everything. The display levels are as follows:
     1022       
    9911023        \begin{itemize}
    9921024                \item DisplayLevel.Beginner
     
    9951027                \item DisplayLevel.Professional
    9961028        \end{itemize}
    997         \item QuickWatchFormat = defines how the content of the property will be shown in the quick watch. CrypTool accepts the following quick watch formats:
     1029\clearpage
     1030       
     1031        \item quickWatchFormat --- determines how the content of the property will be shown in the quickwatch perspective. CrypTool accepts the following quickwatch formats:
     1032       
    9981033        \begin{itemize}
    9991034                \item QuickWatchFormat.Base64
    10001035                \item QuickWatchFormat.Hex
    10011036                \item QuickWatchFormat.None
    1002                 \item QuickWatchFormat.Text\\
    1003                 A quick watch in Hex could look like this:
     1037                \item QuickWatchFormat.Text
     1038        \end{itemize}
     1039
    10041040\begin{figure}[h]
    10051041        \centering
    10061042                \includegraphics{figures/quick_watch.jpg}
    1007         \caption{Possible quick watch}
     1043        \caption{A quickwatch display in hexadecimal.}
    10081044        \label{fig:quick_watch}
    10091045\end{figure}
    1010         \end{itemize}
    1011         \item quickWatchConversionMethod = this string points to a conversion method; most plugins can use a ''null'' value here, because no conversion is necessary. The QuickWatch function uses system ''default'' encoding to display data. So only if your data is in some other format, like Unicode or UTF8, you have to provide the name of a conversion method as string. The method header has to look like this:
     1046       
     1047        \item quickWatchConversionMethod --- this is used to indicate a conversion method; most plugins do not ned to convert their data and thus should use a null value here. The quickwatch function uses the ``default'' system encoding to display data, so if your data is in another other format, such as Unicode or UTF-8, you should provide here the name of a conversion method as string. The method header for such a method should look something like the following:
     1048
    10121049\begin{lstlisting}
    10131050object YourMethodName(string PropertyNameToConvert)
    10141051\end{lstlisting}
     1052
    10151053\end{itemize}
    1016 First we define the ''InputString'' property getter and setter which is needed to provide our plugin with data which has to be encrypted or decrypted:
    1017 \begin{lstlisting}
    1018 [PropertyInfo(Direction.InputData, ''Text input'', ''Input a string to be processed by the Caesar cipher'', '''', true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
     1054
     1055The first of the five properties that we will define is ``InputString''. This is used to provide our plugin with the data to be encrypted or decrypted:
     1056
     1057\begin{lstlisting}
     1058[PropertyInfo(Direction.InputData, "Text input", "Input a string to be processed by the Caesar cipher", "", true, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
    10191059public string InputString
    10201060{
     
    10251065                {
    10261066                        this.inputString = value;
    1027                         OnPropertyChanged(''InputString'');
     1067                        OnPropertyChanged("InputString");
    10281068                }
    10291069        }
    10301070}
    10311071\end{lstlisting}
    1032 In the getter we return the value of the input data.\\\\
    1033 \textit{\small Note 1: It is currently not possible to read directly from the input data stream without creating an intermediate CryptoolStream.\\\\
    1034 \small Note 2: The naming may be confusing. The new CryptoolStream is not an output stream, but it is added to the list of output streams to enable a clean dispose afterwards. See chapter 9 below.\\\\}
    1035 The setter checkes if the input value has changed and sets the new input data and announces the data to the CrypTool 2.0 environment by using the expression ''OnPropertyChanged($<$Property name$>$)''. For input properties this step is necessary to update the quick watch view.\\
    1036 The output data property (which provides the encrypted or decrypted input data) could look like this:
    1037 \begin{lstlisting}
    1038 [PropertyInfo(Direction.OutputData, ''Text output'', ''The string after processing with the Caesar cipher'', '''', false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
     1072
     1073In the get method we simply return the value of the input data. The set method checks if the input value has changed, and, if so, sets the new input data and announces the change to the CrypTool 2 environment by calling the function ``OnPropertyChanged(\textit{$<$Property name$>$})''. This step is necessary for input properties to update the quickwatch view.
     1074\clearpage
     1075
     1076%\textit{\small Note 1: It is currently not possible to read directly from the input data stream without creating an intermediate CryptoolStream.\\\\
     1077%\small Note 2: The naming may be confusing. The new CryptoolStream is not an output stream, but it is added to the list of output streams to enable a clean dispose afterwards. See chapter 9 below.\\\\}
     1078
     1079The output data property (which handles the input data after it has been encrypted or decrypted) will in our example look as follows:
     1080
     1081\begin{lstlisting}
     1082[PropertyInfo(Direction.OutputData, "Text output", "The string after processing with the Caesar cipher", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
    10391083public string OutputString
    10401084{
     
    10431087        {
    10441088                outputString = value;
    1045                 OnPropertyChanged(''OutputString'');
     1089                OnPropertyChanged("OutputString");
    10461090        }
    10471091}
    10481092\end{lstlisting}
    1049 CrypTool does not require implementing output setters, as they will never be called from outside of the plugin. Nevertheless in this example our plugin accesses the property itself, therefore we chose to implement the setter.\\
    1050 You can also provide additional output data types if you like. For example we provide also an output data of type CryptoolStream, an input data for external alphabets and an input data for the shift value of our Caesar algorithm:
    1051 \begin{lstlisting}
    1052 [PropertyInfo(Direction.OutputData, ''propStreamOutputToolTip'', ''propStreamOutputDescription'', '''', false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
     1093
     1094\ \\
     1095\indent CrypTool 2 does not require implementing output set methods, as they will never be called from outside the plugin. Nevertheless, in our example the plugin accesses the property itself, and therefore we have chosen to implement the set method.
     1096
     1097You can provide additional output data types if you so desire. In our example, we will also offer output data of type CryptoolStream, input data for external alphabets, and input data for the shift value of our Caesar algorithm. Note that for the first of these, the set method is not implemented since it will never be called. We shall define these properties as follows:
     1098
     1099\begin{lstlisting}
     1100[PropertyInfo(Direction.OutputData, "propStreamOutputToolTip", "propStreamOutputDescription", "", false, false, DisplayLevel.Beginner, QuickWatchFormat.Text, null)]
    10531101public CryptoolStream OutputData
    10541102{
     
    10701118}
    10711119
    1072 [PropertyInfo(Direction.InputData, ''External alphabet input'', ''Input a string containing the alphabet which should be used by Caesar.\nIf no alphabet is provided on this input, the internal alphabet will be used.'', '''', false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
     1120[PropertyInfo(Direction.InputData, "External alphabet input", "Input a string containing the alphabet to be used by Caesar.\nIf no alphabet is provided for this input, the internal default alphabet will be used.", "", false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
    10731121public string InputAlphabet
    10741122{
     
    10841132}
    10851133
    1086 [PropertyInfo(Direction.InputData, ''Shift value (integer)'', ''Same setting as Shift value in Settings-Pane but as dynamic input.'', '''', false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
     1134[PropertyInfo(Direction.InputData, "Shift value (integer)", "This is the same setting as the shift value in the Settings pane but as dynamic input.", "", false, false, DisplayLevel.Expert, QuickWatchFormat.Text, null)]
    10871135public int ShiftKey
    10881136{
     
    10971145}
    10981146\end{lstlisting}
    1099 This property's setter is not called and therefore not implemented.\\
    1100 The CrypTool-API provides two methods to send messages to the CrypTool. The method ''GuiLogMessage'' is used to send messages to the CrypTool status bar. This is a nice feature to inform the user what your plugin is currently doing.
     1147
     1148\ \\
     1149\indent The CrypTool 2 API provides two methods to send messages from the plugin to the CrypTool 2 core: ``GuiLogMessage'' (used to send messages to the CrypTool 2 status bar) and ``OnPropertyChanged'' (used to inform the core of changes to the plugin data). The ``GuiLogMessage'' method is a nice mechanism to inform the user as to what your plugin is currently doing.
     1150
    11011151\begin{figure}[h]
    11021152        \centering
    11031153                \includegraphics[width=1.00\textwidth]{figures/status_bar.jpg}
    1104         \caption{Status Bar}
     1154        \caption{An example status bar.}
    11051155        \label{fig:status_bar}
    1106 \end{figure}\\
    1107 The method takes two parameters which are:
     1156\end{figure}
     1157\clearpage
     1158
     1159The method takes two parameters:
     1160
    11081161\begin{itemize}
    1109         \item Message = will be shown in the status bar and is of type string
    1110         \item NotificationLevel = to group the messages to their alert level
     1162        \item Message --- the text (of type string) to be shown in the status bar.
     1163        \item NotificationLevel --- the type of message, that is, its alert level:
    11111164        \begin{itemize}
    11121165                \item NotificationLevel.Error
     
    11161169        \end{itemize}
    11171170\end{itemize}
    1118 As we can recognize we have two methods named ''OnPropertyChanged'' and ''GuiLogMessage'' which are not defined. So we have to define these two methods as you can see below:
     1171
     1172Outlines of both of the related events will have been automatically generated by implementing the interface (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}), but we must define appropriate methods as follows:
     1173
    11191174\begin{lstlisting}
    11201175public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
     
    11311186}
    11321187\end{lstlisting}
    1133 To use the ''PropertyChangedEventHandler'' you have to include the namespace ''System.ComponentModel''.\\
    1134 Our whole included namespaces looks now like this:
     1188
     1189\ \\
     1190\indent Note that to use ``PropertyChangedEventHandler'' you must include the namespace ``System.\linebreak ComponentModel''. Our collection of included namespaces should now look as follows:
     1191
    11351192\begin{lstlisting}
    11361193using System.Collections.Generic;
    11371194using System.Text;
    11381195using System.ComponentModel;
    1139 using System.Windows.Control;
     1196using System.Windows.Controls;
    11401197
    11411198using Cryptool.PluginBase;
     
    11441201using Cryptool.PluginBase.Miscellaneous;
    11451202\end{lstlisting}
    1146 \section{Complete the actual code for the class Caesar}\label{sec:CompleteTheActualCodeForTheClassCaesar}
    1147 Up to now, the plugin is ready for the CrypTool base application to be accepted and been shown correctly in the CrypTool menu. What we need now, is the implementation of the actual algorithm in the function ''Execute()'' which is up to you as the plugin developer. CrypTool will always call first the Execute() function.If you place the whole algorithm in this function or split in other as needed is also up to you.
    1148 
    1149 We decided to split our algorithm encryption and decryption in two separate functions, which finally call the function ProcessCaesar.
    1150 
    1151 Let us demonstrate the Execute() function, too:
     1203\clearpage
     1204
     1205\section{Completing the algorithmic code of the Caesar class}
     1206\label{sec:CompletingTheAlgorithmicCodeOfTheCaesarClass}
     1207
     1208At this point, the plugin should be ready to be read by and shown correctly in the CrypTool 2 application. However, we haven't actually implemented the algorithm yet. This should be done in the ``Execute()'' function, as this is what CrypTool 2 will always call first. The actual functionality of your algorithm, as well as the structure thereof, is up to you. Note that an outline of the ``Execute()'' function will have been automatically generated by implementing the interface (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}).
     1209
     1210We have chosen to split our algorithm's encryption and decryption into two separate functions, which will both ultimately call the ``ProcessCaesar()'' function. Below is our implementation of the Execute() function:
     1211
    11521212\begin{lstlisting}
    11531213private void ProcessCaesar(CaesarMode mode)
    11541214{
    11551215        CaesarSettings cfg = (CaesarSettings)this.settings;
    1156         StringBuilder output = new StringBuilder('''');
     1216        StringBuilder output = new StringBuilder("");
    11571217        string alphabet = cfg.AlphabetSymbols;
    11581218
    1159   // in case we want don't consider case in the alphabet, we use only capital letters, hence transform
    1160         // the whole alphabet to uppercase
     1219        // In case we are working in case-insensitive mode, we will use
     1220        // only capital letters, hence we must transform the whole alphabet
     1221        // to uppercase.
    11611222        if (!cfg.CaseSensitiveAlphabet)
    11621223        {
    1163                 alphabet = cfg.AlphabetSymbols.ToUpper(); ;
     1224                alphabet = cfg.AlphabetSymbols.ToUpper();
    11641225        }
    11651226
     
    11681229                for (int i = 0; i < inputString.Length; i++)
    11691230                {
    1170                         // get plaintext char which is currently processed
     1231                        // Get the plaintext char currently being processed.
    11711232                        char currentchar = inputString[i];
    11721233
    1173                         // remember if it is upper case (otherwise lowercase is assumed)
     1234                        // Store whether it is upper case (otherwise lowercase is assumed).
    11741235                        bool uppercase = char.IsUpper(currentchar);
    11751236
    1176                         // get the position of the plaintext character in the alphabet
     1237                        // Get the position of the plaintext character in the alphabet.
    11771238                        int ppos = 0;
    11781239                        if (cfg.CaseSensitiveAlphabet)
     
    11871248                        if (ppos >= 0)
    11881249                        {
    1189                                 // we found the plaintext character in the alphabet, hence we do the shifting
    1190                                 int cpos = 0; ;
     1250                                // We found the plaintext character in the alphabet,
     1251                                // hence we will commence shifting.
     1252                                int cpos = 0;
    11911253                                switch (mode)
    11921254                                {
     
    11991261                                }
    12001262
    1201                                 // we have the position of the ciphertext character, hence just output it in the correct case
     1263                                // We have the position of the ciphertext character,
     1264                                // hence just output it in the correct case.
    12021265                                if (cfg.CaseSensitiveAlphabet)
    12031266                                {
     
    12181281                        else
    12191282                        {
    1220                                 // the plaintext character was not found in the alphabet, hence proceed with handling unknown characters
     1283                                // The plaintext character was not found in the alphabet,
     1284                                // hence proceed with handling unknown characters.
    12211285                                switch ((CaesarSettings.UnknownSymbolHandlingMode)cfg.UnknownSymbolHandling)
    12221286                                {
     
    12301294                        }
    12311295
    1232                         //show the progress
     1296                        // Show the progress.
    12331297                        if (OnPluginProgressChanged != null)
    12341298                        {
     
    12371301                }
    12381302                outputString = output.ToString();
    1239                 OnPropertyChanged(''OutputString'');
    1240                 OnPropertyChanged(''OutputData'');
     1303                OnPropertyChanged("OutputString");
     1304                OnPropertyChanged("OutputData");
    12411305        }
    12421306}
     
    12571321        {
    12581322                case 0:
    1259                         Caesar_LogMessage(''encrypting'', NotificationLevel.Debug);
     1323                        Caesar_LogMessage("Encrypting", NotificationLevel.Debug);
    12601324                        Encrypt();
    12611325                        break;
    12621326                case 1:
     1327                        Caesar_LogMessage("Decrypting", NotificationLevel.Debug);
    12631328                        Decrypt();
    12641329                        break;
     
    12681333}
    12691334\end{lstlisting}
    1270 It is important to make sure that all changes of output properties will be announced to the CrypTool environment. In this example this happens by calling the setter of OutputData which in turn calls ''OnPropertyChanged'' for both output properties ''OutputData'' and ''OutputDataStream''. Instead of calling the property's setter you can as well call ''OnPropertyChanged'' directly within the ''Execute()'' method.\clearpage
    1271 Certainly you have seen the unknown method ''ProgressChanged'' which you can use to show the current algorithm process as a progress on the plugin icon.
    1272 To use this method you also have to declare this method to afford a successful compilation:
     1335
     1336It is important to make sure that all changes to the output properties will be announced to the CrypTool 2 environment. In our example this happens by calling the set method of OutputData, which in turn calls ``OnPropertyChanged'' for both output properties ``OutputData'' and ``OutputDataStream''. Instead of calling the property's set method you can instead call ``OnPropertyChanged'' directly within the ``Execute()'' method.\clearpage
     1337
     1338You have probably noticed that the ``ProgressChanged'' method is undefined. This can be used to show the current algorithm process as a progress bar in the plugin icon. To use this method and compile successfully, you must declare this method, as we have done for our example below:
     1339
    12731340\begin{lstlisting}
    12741341public event PluginProgressChangedEventHandler OnPluginProgressChanged;
     
    12781345}
    12791346\end{lstlisting}
    1280 \section{Perform a clean dispose}\label{sec:PerformACleanDispose}
    1281 Be sure you have closed and cleaned all your streams after execution and when CrypTool decides to dispose the plugin instance. Though not required, we run the dispose code before execution as well:
     1347
     1348\section{Performing a clean dispose}
     1349\label{sec:PerformingACleanDispose}
     1350
     1351Be sure you have closed and cleaned all your streams after execution before CrypTool 2 decides to dispose the plugin instance. Though not required, we will run the disposal code before execution as well. We will expand the associated automatically generated methods (see Section \ref{sec:AddingInterfaceFunctionsToTheCaesarClass}) as follows:
     1352
    12821353\begin{lstlisting}
    12831354public void Dispose()
     
    12991370        Dispose();
    13001371}
    1301 \end{lstlisting}\clearpage
    1302 \section{Finish implementation}\label{sec:FinishImplementation}
    1303 When adding plugin instances to the CrypTool workspace, CrypTool checks whether the plugin runs without any exception. If any IPlugin method throws an exception, CrypTool will show an error and prohibit using the plugin. Therefore we have to remove the ''NotImplementedException'' from the methods ''Initialize()'', ''Pause()'' and ''Stop()''. In our example it's sufficient to provide empty implementations.
     1372\end{lstlisting}
     1373\clearpage
     1374
     1375\section{Finishing the implementation}
     1376\label{sec:FinishingTheImplementation}
     1377
     1378When adding plugin instances to the CrypTool 2 workspace, the application core checks whether the plugin runs without any exceptions. If any method inherited from IPlugin throws an exception, CrypTool 2 will display an error message and prohibit use of the plugin. Therefore, we must remove the ``NotImplementedException'' from the automatically generated methods ``Initialize()'', ``Pause()'' and ``Stop()''. In our example it will be sufficient to provide empty implementations.
     1379
    13041380\begin{lstlisting}
    13051381public void Initialize()
     
    13151391}
    13161392\end{lstlisting}
    1317 The methods ''Presentation()'' and ''QuickWatchPresentation()'' can be used if a plugin developer wants to provide an own visualization of the plugin algorithm which will be shown in CrypTool. Take a look at the PRESENT plugin to see how a custom visualization can be realized. For our Caesar example we don't want to implement a custom visualization, therefore we return ''null'':
     1393
     1394The methods ``Presentation()'' and ``QuickWatchPresentation()'' can be used to provide a specialized visualization of the plugin algorithm to be shown in CrypTool. Take a look at the ``PRESENT'' plugin to see how a custom visualization can be realized. For our Caesar example, we have chosen not to implement a custom visualization. Therefore we will simply return ``null'':
     1395
    13181396\begin{lstlisting}
    13191397public UserControl Presentation
     
    13271405}
    13281406\end{lstlisting}
    1329 Your plugin should compile without errors at this point.\clearpage
    1330 
    1331 \section{Import the plugin to CrypTool and test it}\label{sec:ImportThePluginToCryptoolAndTestIt}
    1332 After you have built the plugin, you need to move the newly created plugin DLL to a location, where CrypTool can find it. To do this, there are the following ways:
    1333 \begin{itemize}
    1334         \item Copy your plugin DLL file in the folder ''CrypPlugins'' which has to be in the same folder as the CrypTool executable, called ''CrypWin.exe''. If necessary, create the folder ''CrypPlugins''.
     1407
     1408Your plugin should compile without errors at this point.
     1409\clearpage
     1410
     1411\section{Importing and testing the plugin}
     1412\label{sec:ImportingAndTestingThePlugin}
     1413
     1414After you have built the plugin, you need to move the newly created plugin DLL to a location where CrypTool 2 can find it. There are a few different ways to accomplish this. You can find the DLL file in \textit{\textbackslash CrypPluginBase\textbackslash bin\textbackslash Debug}.
     1415
     1416\subsection{Global storage}
     1417\label{sec:GlobalStorage}
     1418
     1419The first option is to copy your plugin's DLL file to the ``CrypPlugins'' folder in which the CrypTool 2 executable (``CrypWin.exe'') can be found. %If necessary, create the folder ''CrypPlugins''.
     1420
    13351421\begin{figure}[h]
    13361422        \centering
    13371423                \includegraphics{figures/copy_dll_global_storage.jpg}
    1338         \caption{Copy plugin to global storage}
     1424        \caption{Copying the plugin to the global storage folder}
    13391425        \label{fig:copy_dll_global_storage}
    13401426\end{figure}
    13411427
    1342 This folder is called ''Global storage'' in the CrypTool architecture. Changes in this folder will take effect for all users on a multi user Windows. Finally restart CrypTool.\clearpage
     1428This folder is known as ``global storage'' in the CrypTool 2 architecture. Changes in this folder will affect all users on a multi-user Windows platform. You should now restart CrypTool 2.
     1429\clearpage
     1430
    13431431\begin{figure}[h]
    13441432        \centering
    13451433                \includegraphics{figures/global_storage.jpg}
    1346         \caption{Plugins global storage}
     1434        \caption{Inside the CrypPlugins folder (the global storage).}
    13471435        \label{fig:global_storage}
    13481436\end{figure}
    13491437
    1350         \item Copy your plugin DLL file in the folder ''CrypPlugins'' which is located in your home path in the folder ''ApplicationData'' and restart CrypTool.  This home folder path is called ''Custom storage'' in the CrypTool architecture. Changes in this folder will only take effect for current user.  On a German Windows XP the home folder path could look like:
    1351 ''C:\textbackslash Dokumente und Einstellungen\textbackslash $<$User$>$\textbackslash Anwendungsdaten\textbackslash CrypPlugins'' and in Vista/Windows7 the path will look like ''C:\textbackslash Users\textbackslash $<$user$>$\textbackslash Application Data\textbackslash CrypPlugins''.\clearpage
     1438\subsection{Custom storage}
     1439\label{sec:CustomStorage}
     1440
     1441The second possibility is to copy your plugin's DLL file to the ``CrypPlugins'' folder located in the ``Application Data'' folder in your home folder. In Windows XP, the home folder path should be as follows: \textit{C:\textbackslash Documents and Settings\textbackslash $<$user name$>$\textbackslash Application Data\textbackslash CrypPlugins}, and in Vista and Windows 7 the path should look like: \textit{C:\textbackslash Users\textbackslash $<$user name$>$\textbackslash Application Data\textbackslash CrypPlugins}. This home folder path is called ``custom storage'' in the CrypTool architecture. Changes in this folder will only take effect for current user. After copying the file, you must restart CrypTool 2.
     1442\clearpage
     1443
    13521444\begin{figure}[h]
    13531445        \centering
    13541446                \includegraphics[width=1.00\textwidth]{figures/custom_storage.jpg}
    1355         \caption{Plugins custom storage}
     1447        \caption{The custom storage folder.}
    13561448        \label{fig:custom_storage}
    13571449\end{figure}
    1358         \item You can also import new plugins directly from the CrypTool interface. Just execute CrypWin.exe and select the ''Download Plugins'' button. An ''Open File Dialog'' will open and ask where the new plugin is located. After selecting the new plugin, CrypTool will automatically import the new plugin in the custom storage folder. With this option you will not have to restart CrypTool. All according menu entries will be updated automatically.
    1359 Notice, that this plugin importing function only accepts \textbf{signed} plugins.
    1360 
    1361 \textit{\small Note: This option is a temporary solution for importing new plugins. In the future this will be done online by a web service.}\clearpage
    1362 
    1363         \item Use post-build in your project properties to copy the DLL automatically after building it in Visual Studio with other plugins. Right-click on your plugin project and select ''Properties'':
     1450
     1451\subsection{Importing directly}
     1452\label{sec:ImportingDirectly}
     1453
     1454Alternatively, you can import new plugins directly from the CrypTool 2 interface. Just run \mbox{CrypWin.exe} and select the ``Download Plugins'' button. An ``Open File Dialog'' window will open and ask where the new plugin is located. After selecting the new plugin, CrypTool 2 will automatically import the plugin to the custom storage folder. With this option you will not have to restart the program. All corresponding menu entries will be updated automatically. Note that this import function only accepts \textbf{signed} plugins, and also that this option is just a temporary solution: in the future this will be done online by a web service.
     1455\clearpage
     1456
     1457\subsection{Using build settings}
     1458\label{sec:UsingBuildSettings}
     1459
     1460Yet another option is to use the build settings in your plugin's project properties to copy the DLL automatically after building it in Visual Studio. To set this up, right-click on your plugin project and select ``Properties'':
     1461
    13641462\begin{figure}[h]
    13651463        \centering
    13661464                \includegraphics{figures/solution_properties.JPG}
    1367         \caption{Solution Properties}
     1465        \caption{Selecting the solution properties.}
    13681466        \label{fig:solution_properties}
    1369 \end{figure}\clearpage
    1370 Select ''Build Events'':
     1467\end{figure}
     1468\clearpage
     1469
     1470\noindent Then select ``Build Events'':
     1471
    13711472\begin{figure}[h]
    13721473        \centering
    13731474                \includegraphics{figures/post_build.JPG}
    1374         \caption{Build Events}
     1475        \caption{Setting the build events.}
    13751476        \label{fig:post_build}
    13761477\end{figure}
    13771478
    1378 Enter the following text snippet into ''Post-build event command line'':\\\\
    1379 cd ''\$(ProjectDir)''\\
     1479\noindent And finally, enter the following text into ``Post-build event command line'':\\\\
     1480cd "\$(ProjectDir)" \\
    13801481cd ..\textbackslash ..\textbackslash CrypWin\$(OutDir)\\
    1381 if not exist ''./CrypPlugins'' mkdir ''./CrypPlugins''\\
    1382 del /F /S /Q /s /q ''\fcolorbox{yellow}{yellow}{Caesar}*.*''\\
    1383 copy ''\$(TargetDir)\fcolorbox{yellow}{yellow}{Caesar}*.*'' ''./CrypPlugins''\\\\
    1384 You need to adapt the yellow marked field to your actual project name.
    1385 \end{itemize}
    1386 
    1387 
    1388 \section{Source code and source template}\label{sec:SourceCodeAndSourceTemplate}
    1389 Here you can download the whole source code which was presented in this ''Howto'' as a Visual Studio \textbf{solution}:\\\\
     1482if not exist "./CrypPlugins" mkdir "./CrypPlugins"\\
     1483del /F /S /Q /s /q "\fcolorbox{yellow}{yellow}{Caesar}*.*"\\
     1484copy "\$(TargetDir)\fcolorbox{yellow}{yellow}{Caesar}*.*" "./CrypPlugins"\\\\
     1485You will need to change the marked fields to your particular plugin's name.
     1486
     1487\section{Downloading the example and template}
     1488\label{sec:DownloadingTheExampleAndTemplate}
     1489
     1490If you didn't download the entire CrypTool 2 source code as described in Section \ref{TheCrypTool2SVNURL}, but you want a copy of the source code for the Caesar algorithm that was used as an example in this guide, you can download it as a Visual Studio \textbf{solution} from the following location:\\\\
    13901491\textit{username: anonymous\\
    1391 password: not required\\}
     1492password:} (not required)\\
    13921493\htmladdnormallink{https://www.cryptool.org/svn/CrypTool2/trunk/CrypPlugins/Caesar/}{https://www.cryptool.org/svn/CrypTool2/trunk/CrypPlugins/Caesar/}\\\\
    1393 %\textit{\small Note: You should commit your sources to our subversion so often you can. This will ensure your interoperability for further development.}\\\\
    1394 Here you can download the Visual Studio plugin \textbf{template} to begin with the development of a new CrypTool plugin:\\\\
    1395 \htmladdnormallink{http://cryptool2.vs.uni-due.de/downloads/template/encryptionplugin.zip}{http://cryptool2.vs.uni-due.de/downloads/template/encryptionplugin.zip}\clearpage
    1396 \section{Provide a workflow file of your plugin}\label{ProvideAWorkflowFileOfYourPlugin}
    1397 Every plugin developer should provide a workflow file which shows his algorithm working in CrypTool2. You will automatically create a workflow file by saving your project which was created on CrypTool2 work space. Here is an example how a workflow could look like:
     1494We have also created a Visual Studio plugin template to help with the development of new plugins. This can be found here:\\\\
     1495\htmladdnormallink{http://cryptool2.vs.uni-due.de/downloads/template/encryptionplugin.zip}{http://cryptool2.vs.uni-due.de/downloads/template/encryptionplugin.zip}
     1496\clearpage
     1497
     1498\section{Drawing the workflow of your plugin}
     1499\label{DrawingTheWorkfloweOfYourPlugin}
     1500
     1501Each plugin should have an associated workflow file to show the algorithm in action in CrypTool 2. Such a file can be automatically created by simply saving a CrypTool 2 workspace project featuring your plugin. Below is a possible workflow for our Caesar example:
     1502
    13981503\begin{figure}[h]
    13991504        \centering
    14001505                \includegraphics{figures/sample.jpg}
    1401         \caption{Plugin sample}
     1506        \caption{A sample workflow diagram for the Caesar algorithm.}
    14021507        \label{fig:sample}
    14031508\end{figure}
Note: See TracChangeset for help on using the changeset viewer.