diff --git a/luennot/live21/Siirra/Siirra.cs b/luennot/live21/Siirra/Siirra.cs
index 8f784d864577b8515d5b40a40bf1977ff671e2e5..27a95052f6adbcc56873537418b36b90e9482b7f 100644
--- a/luennot/live21/Siirra/Siirra.cs
+++ b/luennot/live21/Siirra/Siirra.cs
@@ -1,7 +1,7 @@
 using System;
 using System.Text;
 /// @author  Vesa Lappalainen
-/// @version 15.11.2021
+/// @version 15.11.2023
 /// <summary>
 ///  Lasketaan vokaaleja
 /// </summary>
@@ -13,14 +13,59 @@ public class Siirra
     /// </summary>
     public static void Main()
     {
-        string jono = "Mieleni minun tekevi, aivoni ajattelevi";
+        StringBuilder jono = new StringBuilder("Mieleni minun tekevi, aivoni ajattelevi");
         string vokaalit = "aeiouyåäö";
         int maara = 3;
 
-        string jonon3EnsimmaistaVokaalia = ""; // SiirraKirjaimet(jono,vokaalit,maara);
+        string jonon3EnsimmaistaVokaalia = SiirraKirjaimet(jono,vokaalit,maara);
 
         Console.WriteLine("Jono:  " + jono); // Mlni minun tekevi, aivoni ajattelevi
         Console.WriteLine("3 vok: " + jonon3EnsimmaistaVokaalia); // iee
     }
+    
+    /// <summary>
+    /// Poistetaan jonosta korkeintaan maxMaara kappaletta
+    /// joukon siirrettavat kirjaimia.
+    /// </summary>
+    /// <param name="jono">mistä poistetaan</param>         
+    /// <param name="siirrettavat">mitä kirjaimia poistetaan</param> 
+    /// <param name="maxMaara">montako korkeintaan poistetaan</param> 
+    /// <returns>siirretyt merkit</returns>
+    /// <example>
+    /// <pre name="test">
+    ///   StringBuilder jono = new StringBuilder("kissa istuu");
+    ///   SiirraKirjaimet(jono,"",1)    === "";    jono =S= "kissa istuu";
+    ///   SiirraKirjaimet(jono,"xyz",1) === "";    jono =S= "kissa istuu";
+    ///   SiirraKirjaimet(jono,"aus",0) === "";    jono =S= "kissa istuu";
+    ///   SiirraKirjaimet(jono,"i",1)   === "i";   jono =S= "kssa istuu";
+    ///   SiirraKirjaimet(jono,"s",2)   === "ss";  jono =S= "ka istuu";
+    ///   SiirraKirjaimet(jono,"aus",3) === "asu"; jono =S= "k itu";
+    ///   SiirraKirjaimet(jono,"iu",3)  === "iu";  jono =S= "k t";
+    ///   SiirraKirjaimet(jono," ",1)   === " ";   jono =S= "kt";
+    ///   SiirraKirjaimet(jono,"kt",5)  === "kt";  jono =S= "";
+    ///   SiirraKirjaimet(jono,"kt",5)  === "";    jono =S= "";
+    /// </pre>
+    /// </example>
+    public static string SiirraKirjaimet(StringBuilder jono ,string siirrettavat ,int maxMaara)
+    {
+        // otetaan seuraava jonon kirjain 
+        // ja jos se on siirrettavat joukossa, 
+        // niin poistetaan kirjain jonosta
+        StringBuilder tulos = new StringBuilder();
+
+        int i = 0;
+        while ( i < jono.Length && tulos.Length < maxMaara )
+        {
+            char merkki = jono[i];
+            if (siirrettavat.IndexOf(merkki) >= 0)
+            {
+                jono.Remove(i, 1);
+                tulos.Append(merkki);
+            }
+            else i++;
+        }
+        return tulos.ToString(); // 
+    }
+
 }
 // BYCODEEND
\ No newline at end of file
diff --git a/luennot/live21/SiirraTest/SiirraTest.cs b/luennot/live21/SiirraTest/SiirraTest.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7bda7ba995448db55c01627ffb2fe951dccad0c0
--- /dev/null
+++ b/luennot/live21/SiirraTest/SiirraTest.cs
@@ -0,0 +1,77 @@
+// ReSharper disable all
+using System;
+using System.Text;
+using NUnit.Framework;
+using static Siirra;
+
+	[TestFixture]
+	[DefaultFloatingPointTolerance(0.000001)]
+	public  class TestSiirra
+	{
+		[Test]
+		public  void TestSiirraKirjaimet35()
+		{
+			StringBuilder jono = new StringBuilder("kissa istuu");
+			Assert.AreEqual( "", SiirraKirjaimet(jono,"",1)    , "in method SiirraKirjaimet, line 37");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "kissa istuu").ToString(), (    jono ).ToString(), "in method SiirraKirjaimet, line 37");
+			Assert.AreEqual( "", SiirraKirjaimet(jono,"xyz",1) , "in method SiirraKirjaimet, line 38");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "kissa istuu").ToString(), (    jono ).ToString(), "in method SiirraKirjaimet, line 38");
+			Assert.AreEqual( "", SiirraKirjaimet(jono,"aus",0) , "in method SiirraKirjaimet, line 39");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "kissa istuu").ToString(), (    jono ).ToString(), "in method SiirraKirjaimet, line 39");
+			Assert.AreEqual( "i", SiirraKirjaimet(jono,"i",1)   , "in method SiirraKirjaimet, line 40");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "kssa istuu").ToString(), (   jono ).ToString(), "in method SiirraKirjaimet, line 40");
+			Assert.AreEqual( "ss", SiirraKirjaimet(jono,"s",2)   , "in method SiirraKirjaimet, line 41");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "ka istuu").ToString(), (  jono ).ToString(), "in method SiirraKirjaimet, line 41");
+			Assert.AreEqual( "asu", SiirraKirjaimet(jono,"aus",3) , "in method SiirraKirjaimet, line 42");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "k itu").ToString(), ( jono ).ToString(), "in method SiirraKirjaimet, line 42");
+			Assert.AreEqual( "iu", SiirraKirjaimet(jono,"iu",3)  , "in method SiirraKirjaimet, line 43");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "k t").ToString(), (  jono ).ToString(), "in method SiirraKirjaimet, line 43");
+			Assert.AreEqual( " ", SiirraKirjaimet(jono," ",1)   , "in method SiirraKirjaimet, line 44");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "kt").ToString(), (   jono ).ToString(), "in method SiirraKirjaimet, line 44");
+			Assert.AreEqual( "kt", SiirraKirjaimet(jono,"kt",5)  , "in method SiirraKirjaimet, line 45");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "").ToString(), (  jono ).ToString(), "in method SiirraKirjaimet, line 45");
+			Assert.AreEqual( "", SiirraKirjaimet(jono,"kt",5)  , "in method SiirraKirjaimet, line 46");;
+			;
+			;
+			;
+			;
+			Assert.AreEqual(( "").ToString(), (    jono ).ToString(), "in method SiirraKirjaimet, line 46");
+		}
+	}
+
diff --git a/luennot/live21/SiirraTest/SiirraTest.csproj b/luennot/live21/SiirraTest/SiirraTest.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..abd2b086d8afe52cc7cfc14cc8fcd02ce23116c4
--- /dev/null
+++ b/luennot/live21/SiirraTest/SiirraTest.csproj
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Project Sdk="Microsoft.NET.Sdk">
+    <PropertyGroup>
+        <TargetFramework>net7.0</TargetFramework>
+        <IsPackable>false</IsPackable>
+    </PropertyGroup>
+    <ItemGroup>
+        <PackageReference Include="NUnit" Version="3.13.1"/>
+        <PackageReference Include="NUnit3TestAdapter" Version="3.17.0"/>
+        <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3"/>
+    </ItemGroup>
+    <ItemGroup>
+        <ProjectReference Include="..\Siirra\Siirra.csproj"/>
+    </ItemGroup>
+</Project>
diff --git a/luennot/live21/live21.sln b/luennot/live21/live21.sln
index 7867a02a6eb0ac549ad2263f162e94a47a340701..00f9cfcb3db9f345051e175e5d19dd4da4f50431 100644
--- a/luennot/live21/live21.sln
+++ b/luennot/live21/live21.sln
@@ -1,16 +1,23 @@
 
 Microsoft Visual Studio Solution File, Format Version 12.00
+
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Siirra", "Siirra\Siirra.csproj", "{D4C76668-83E0-4E3D-BA48-B3D4113B5430}"
 EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiirraTest", "SiirraTest\SiirraTest.csproj", "{AE9841AA-2C4B-463F-8FB8-2D23211B663D}"
+EndProject
 Global
-	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-		Debug|Any CPU = Debug|Any CPU
-		Release|Any CPU = Release|Any CPU
-	EndGlobalSection
-	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Release|Any CPU.Build.0 = Release|Any CPU
-	EndGlobalSection
+  GlobalSection(SolutionConfigurationPlatforms) = preSolution
+    Debug|Any CPU = Debug|Any CPU
+    Release|Any CPU = Release|Any CPU
+  EndGlobalSection
+  GlobalSection(ProjectConfigurationPlatforms) = postSolution
+    {D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+    {D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Debug|Any CPU.Build.0 = Debug|Any CPU
+    {D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Release|Any CPU.ActiveCfg = Release|Any CPU
+    {D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Release|Any CPU.Build.0 = Release|Any CPU
+    {AE9841AA-2C4B-463F-8FB8-2D23211B663D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+    {AE9841AA-2C4B-463F-8FB8-2D23211B663D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+    {AE9841AA-2C4B-463F-8FB8-2D23211B663D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+    {AE9841AA-2C4B-463F-8FB8-2D23211B663D}.Release|Any CPU.Build.0 = Release|Any CPU
+  EndGlobalSection
 EndGlobal
diff --git a/luennot/live21/live21.sln.ctbackup b/luennot/live21/live21.sln.ctbackup
new file mode 100644
index 0000000000000000000000000000000000000000..7867a02a6eb0ac549ad2263f162e94a47a340701
--- /dev/null
+++ b/luennot/live21/live21.sln.ctbackup
@@ -0,0 +1,16 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Siirra", "Siirra\Siirra.csproj", "{D4C76668-83E0-4E3D-BA48-B3D4113B5430}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{D4C76668-83E0-4E3D-BA48-B3D4113B5430}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+EndGlobal
diff --git a/luennot/luento22/.idea/.idea.luento22/.idea/.gitignore b/luennot/luento22/.idea/.idea.luento22/.idea/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..87c64907b1c11dd3e5fe68372510a3616455c337
--- /dev/null
+++ b/luennot/luento22/.idea/.idea.luento22/.idea/.gitignore
@@ -0,0 +1,13 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Rider ignored files
+/contentModel.xml
+/projectSettingsUpdater.xml
+/.idea.luento22.iml
+/modules.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/luennot/luento22/.idea/.idea.luento22/.idea/encodings.xml b/luennot/luento22/.idea/.idea.luento22/.idea/encodings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..df87cf951fb4858ab7a76b68dd479c98b2df2404
--- /dev/null
+++ b/luennot/luento22/.idea/.idea.luento22/.idea/encodings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
+</project>
\ No newline at end of file
diff --git a/luennot/luento22/.idea/.idea.luento22/.idea/indexLayout.xml b/luennot/luento22/.idea/.idea.luento22/.idea/indexLayout.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7b08163cebc50fb3e777eea4881b68fcebc10590
--- /dev/null
+++ b/luennot/luento22/.idea/.idea.luento22/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="UserContentModel">
+    <attachedFolders />
+    <explicitIncludes />
+    <explicitExcludes />
+  </component>
+</project>
\ No newline at end of file
diff --git a/luennot/luento22/.idea/.idea.luento22/.idea/vcs.xml b/luennot/luento22/.idea/.idea.luento22/.idea/vcs.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2bdec2d71b6a5ce4ae49efc37516809c50e4d5e
--- /dev/null
+++ b/luennot/luento22/.idea/.idea.luento22/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../.." vcs="Git" />
+  </component>
+</project>
\ No newline at end of file