diff --git a/Verkkokauppa.java b/Verkkokauppa.java
new file mode 100644
index 0000000000000000000000000000000000000000..91aac05a4863d39c5a13cdb20b34ff03d923f922
--- /dev/null
+++ b/Verkkokauppa.java
@@ -0,0 +1,261 @@
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class Verkkokauppa {
+    private ArrayList<Asiakas> asiakkaat;
+    private ArrayList<Tuote> tuotteet;
+    private ArrayList<Myyja> myyjat;
+    private ArrayList<Ostotapahtuma> tapahtumat;
+
+    public Verkkokauppa() {
+        asiakkaat = new ArrayList<>();
+        tuotteet = new ArrayList<>();
+        myyjat = new ArrayList<>();
+        tapahtumat = new ArrayList<>();
+    }
+
+    public void lisaaAsiakas(Asiakas asiakas) {
+        asiakkaat.add(asiakas);
+    }
+
+    public void lisaaTuote(Tuote tuote) {
+        tuotteet.add(tuote);
+    }
+
+    public void lisaaMyyja(Myyja myyja) {
+        myyjat.add(myyja);
+    }
+
+    public void lisaaTapahtuma(Ostotapahtuma tapahtuma) {
+        tapahtumat.add(tapahtuma);
+    }
+
+    /**
+     * Yrittää poistaa annetun asiakkaan asiakalistasta.
+     *
+     * @param asiakas asiakas, jonka poistoa yritetään
+     * @return true, jos asiakas löytyi ja poistettiin, muuten false
+     */
+    public boolean poistaAsiakas(Asiakas asiakas) {
+        if (asiakkaat.contains(asiakas)) {
+            asiakkaat.remove(asiakas);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Yrittää poistaa annetun tuotteen tuotelistasta.
+     *
+     * @param tuote tuote, jonka poistoa yritetään
+     * @return true, jos tuote löytyi ja poistettiin, muuten false
+     */
+    public boolean poistaTuote(Tuote tuote) {
+        if (tuotteet.contains(tuote)) {
+            tuotteet.remove(tuote);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Yrittää poistaa annetun myyjän myyjalistasta.
+     *
+     * @param myyja myyja, jonka poistoa yritetään
+     * @return true, jos myyjä löytyi ja poistettiin, muuten false
+     */
+    public boolean poistaMyyja(Myyja myyja) {
+        if (myyjat.contains(myyja)) {
+            myyjat.remove(myyja);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Yrittää poistaa annetun tapahtuman ostotapahtumalistasta.
+     *
+     * @param tapahtuma ostotapahtuma, jonka poistoa yritetään
+     * @return true, jos ostotapahtuma löytyi ja poistettiin, muuten false
+     */
+    public boolean poistaOstotapahtuma(Ostotapahtuma tapahtuma) {
+        if (tapahtumat.contains(tapahtuma)) {
+            tapahtumat.remove(tapahtuma);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Palauttaa annetun asiakasnumeron mukaisen asiakkaan tai
+     * <code>null</code>, jos asiakasta ei löydy
+     *
+     * @param asiakasnumero halutun asiakkaan asiakasnumero
+     * @return pyydetyn asiakkaan tai null, jos asiakasta ei löydy
+     */
+    public Asiakas annaAsiakas(String asiakasnumero) {
+        for (Asiakas asiakas : asiakkaat) {
+            if (asiakas.getAsiakasNumero().equals(asiakasnumero)) {
+                return asiakas;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Palauttaa annetun nimen mukaisen tuotteen tai
+     * <code>null</code>, jos tuotetta ei löydy
+     *
+     * @param nimi halutun tuotteen nimi
+     * @return pyydetyn tuotteen tai null, jos tuotetta ei löydy
+     */
+    public Tuote annaTuote(String nimi) {
+        for (Tuote tuote : tuotteet) {
+            if (tuote.getNimi().equals(nimi)) {
+                return tuote;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Palauttaa annetun tunnisteen mukaisen myyjän tai
+     * <code>null</code>, jos myyjää ei löydy
+     *
+     * @param tunniste halutun myyjän tunniste
+     * @return pyydetyn myyjän tai null, jos myyjää ei löydy
+     */
+    public Myyja annaMyyja(String tunniste) {
+        for (Myyja myyja : myyjat) {
+            if (myyja.getTunniste().equals(tunniste)) {
+                return myyja;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Palauttaa annetun indeksin mukaisen ostotapahtuman listasta.
+     * Huomaa, että indeksointi alkaa nollasta, mutta tapahtumien listaamisessa
+     * indeksit on ilmoitettu alkaen ykkösestä.
+     *
+     * @param indeksi indeksi jonka kohdalta tapahtuma palautetaan
+     * @return annetun indeksin mukaisen ostotapahtuman
+     */
+    public Ostotapahtuma annaTapahtuma(int indeksi) {
+        if (tapahtumat.size() > indeksi) {
+            return tapahtumat.get(indeksi);
+        }
+        return null;
+    }
+
+    /**
+     * Palauttaa kaikki asiakkaat yhtenä merkkijonona.
+     *
+     * @return asiakalistan merkkijonona
+     */
+    public String listaaAsiakkaat() {
+        // Tekee otsikkorivin
+        // \t on tabulaattori, joka tasaa tulosteen
+        // sarakkeisiin; \n tekee rivinvaihdon
+        StringBuilder s = new StringBuilder("Asiakasnumero\tNimi\t\t\tOstoja\tKanta-asiakas\n");
+        for (Asiakas asiakas : asiakkaat) {
+            s.append(asiakas.getAsiakasNumero() + "\t\t\t");
+            s.append(asiakas.getNimi() + "\t");
+            s.append(asiakas.getOstojaTehty() + "\t\t");
+            if (asiakas instanceof KantaAsiakas) {
+                s.append("On\n");
+            } else {
+                s.append("Ei\n");
+            }
+        }
+        return s.toString();
+    }
+
+    /**
+     * Palauttaa kaikki myyjät yhtenä merkkijonona
+     *
+     * @return myyjät merkkijonona
+     */
+    public String listaaMyyjat() {
+        // Tekee otsikkorivin
+        // \t on tabulaattori, joka tasaa tulosteen
+        // sarakkeisiin; \n tekee rivinvaihdon
+        StringBuilder s = new StringBuilder("Tunniste\tNimi\t\t\tProvisiot\n");
+        for (Myyja myyja : myyjat) {
+            s.append(myyja.getTunniste() + "\t\t");
+            s.append(myyja.getNimi() + "\t\t");
+            s.append(myyja.getProvisiot() + "\n");
+        }
+        return s.toString();
+    }
+
+    /**
+     * Palautta kaikki tuotteet yhtenä merkkijonona.
+     *
+     * @return tuotteet merkkijonona
+     */
+    public String listaaTuotteet() {
+        // Tekee otsikkorivin
+        // \t on tabulaattori, joka tasaa tulosteen
+        // sarakkeisiin; \n tekee rivinvaihdon
+        StringBuilder s = new StringBuilder("Nimi\tSaldo\t\t\tHinta\tVirtuaalinen\n");
+        for (Tuote tuote : tuotteet) {
+            s.append(tuote.getNimi() + "\t");
+            s.append(tuote.getSaldo() + "\t\t");
+            s.append(tuote.getHinta() + "\t");
+            if (tuote instanceof VirtuaalinenTuote) {
+                s.append("Kyllä\n");
+            } else {
+                s.append("Ei\n");
+            }
+        }
+        return s.toString();
+    }
+
+    /**
+     * Palauttaa kaikki tapahtumat yhtenä merkkijonona.
+     *
+     * @return tapahtumat merkkijonona
+     */
+    public String listaaTapahtumat() {
+        StringBuilder s = new StringBuilder("Numero\tTuote\tAsiakas\tMyyjä\tKpl\tHinta\n");
+        int n = 1;
+        for (Ostotapahtuma tapahtuma : tapahtumat) {
+            s.append(n++ + "\t");
+            s.append(tapahtuma.getTuote().getNimi() + "\t");
+            s.append(tapahtuma.getAsiakas().getNimi() + "\t");
+            s.append(tapahtuma.getMyyja().getNimi() + "\t");
+            s.append(tapahtuma.getMaara() + "\t");
+            s.append(tapahtuma.getHinta() + "\n");
+        }
+        return s.toString();
+
+    }
+
+    public void tallenna() {
+        VerkkokauppaIO.kirjoita(asiakkaat, "asiakkaat.dat");
+        VerkkokauppaIO.kirjoita(tuotteet, "tuotteet.dat");
+        VerkkokauppaIO.kirjoita(myyjat, "myyjat.dat");
+        VerkkokauppaIO.kirjoita(tapahtumat, "tapahtumat.dat");
+    }
+
+    public void lataa() {
+        ArrayList<Asiakas> asiakkaatData = VerkkokauppaIO.lue("asiakkaat.dat");
+        if(asiakkaatData != null) {
+            this.asiakkaat = asiakkaatData;
+        }
+        ArrayList<Tuote> tuotteetData = VerkkokauppaIO.lue("tuotteet.dat");
+        if(tuotteetData != null) {
+            this.tuotteet = tuotteetData;
+        }
+        ArrayList<Myyja> myyjatData = VerkkokauppaIO.lue("myyjat.dat");
+        if(myyjatData != null) {
+            this.myyjat = myyjatData;
+        }
+        ArrayList<Ostotapahtuma> tapahtumatData = VerkkokauppaIO.lue("tapahtumat.dat");
+        if(tapahtumatData != null) {
+            this.tapahtumat = tapahtumatData;
+        }
+    }
+}
diff --git a/VerkkokauppaIO.java b/VerkkokauppaIO.java
index 65847d21f2f121782db6378d15d7cfb18a1efe1e..d2f7d97614b1ca305e43dc02823df1fdca99938e 100644
--- a/VerkkokauppaIO.java
+++ b/VerkkokauppaIO.java
@@ -11,64 +11,7 @@ import java.util.Scanner;
 public class VerkkokauppaIO {
 
     public static void main(String[] args) {
-        // Asiakastesti
-        ArrayList<Asiakas> asiakkaat = new ArrayList<>();
-        asiakkaat.add(new Asiakas("1234", "Ukko", 120.0));
-        asiakkaat.add(new KantaAsiakas("2345", "Tauno", 230.0, 5));
-        asiakkaat.add(new Asiakas("3456", "Hessu", 666.0));
-        asiakkaat.add(new KantaAsiakas("4567", "Pöllö", 7200.0, 15));
-        
-        kirjoitaAsiakkaat(asiakkaat, "asiakkaat.dat"); 
-        ArrayList<Asiakas> asiakkaatAgain = new ArrayList<>();
-        asiakkaatAgain = lueAsiakkaat("asiakkaat.dat");
-        for(Asiakas asiakas : asiakkaatAgain) {
-            System.out.println(asiakas.toString());
-        }
-        System.out.println();
-
-        // Tuotetesti
-        ArrayList<Tuote> tuotteet = new ArrayList<>();
-        tuotteet.add(new Tuote("Omena", 50, 4.95));
-        tuotteet.add(new Tuote("Appelsiini", 30, 6.95));
-        tuotteet.add(new Tuote("Banaani", 150, 2.95));
-        tuotteet.add(new VirtuaalinenTuote("Lahjakortti", 100));
 
-        kirjoitaTuotteet(tuotteet, "tuotteet.dat");
-        ArrayList<Tuote> tuotteetAgain = new ArrayList<>();
-        tuotteetAgain = lueTuotteet("tuotteet.dat");
-        for(Tuote tuote : tuotteetAgain) {
-            System.out.println(tuote.toString());
-        }
-        System.out.println();
-        
-        // Myyjatesti
-        ArrayList<Myyja> myyjat = new ArrayList<>();
-        myyjat.add(new Myyja("4321", "Pekka", 10.85));
-        myyjat.add(new Myyja("5432", "Teppo", 215.11));
-        myyjat.add(new Myyja("6543", "Unkero", 11.12));
-        myyjat.add(new Myyja("7654", "Matti", 6.66));
-        
-        kirjoitaMyyjat(myyjat, "myyjat.dat");
-        ArrayList<Myyja> myyjatAgain = new ArrayList<>();
-        myyjatAgain = lueMyyjat("myyjat.dat");
-        for(Myyja myyja : myyjatAgain) {
-            System.out.println(myyja.toString());
-        }
-        System.out.println();
-        
-        // Ostotapahtumatesti
-        ArrayList<Ostotapahtuma> tapahtumat = new ArrayList<>();
-        tapahtumat.add(new Ostotapahtuma(asiakkaat.get(0), myyjat.get(0), tuotteet.get(0), 10));
-        tapahtumat.add(new Ostotapahtuma(asiakkaat.get(1), myyjat.get(1), tuotteet.get(1), 20));
-        tapahtumat.add(new Ostotapahtuma(asiakkaat.get(2), myyjat.get(2), tuotteet.get(2), 30));
-        
-        kirjoitaTapahtumat(tapahtumat, "tapahtumat.dat");
-        ArrayList<Ostotapahtuma> tapahtumatAgain = new ArrayList<>();
-        tapahtumatAgain = lueTapahtumat("tapahtumat.dat");
-        for(Ostotapahtuma tapahtuma : tapahtumatAgain) {
-            System.out.println(tapahtuma.toString());
-        }
-        System.out.println();
     }
 
     private static final String EROTIN = ";";
@@ -107,7 +50,7 @@ public class VerkkokauppaIO {
      * @param asiakasLista  lista kirjoitettavista asiakkaista.
      * @param tiedostonNimi kirjoitettavan tiedoston nimi
      */
-    public static void _kirjoitaAsiakkaat(ArrayList<Asiakas> asiakasLista,
+    public static void kirjoitaAsiakkaat(ArrayList<Asiakas> asiakasLista,
                                          String tiedostonNimi) {
         String data = "";
         for (Asiakas asiakas : asiakasLista) {
@@ -151,7 +94,7 @@ public class VerkkokauppaIO {
      * @param tiedostonNimi luettavan tiedoston nimi
      * @return tiedostosta luetut asiakasoliot listana
      */
-    public static ArrayList<Asiakas> _lueAsiakkaat(String tiedostonNimi) {
+    public static ArrayList<Asiakas> lueAsiakkaat(String tiedostonNimi) {
         ArrayList<Asiakas> asiakkaat = new ArrayList<>();
         ArrayList<String> data = lueTiedosto(tiedostonNimi);
         for (String adata : data) {
@@ -162,135 +105,31 @@ public class VerkkokauppaIO {
     }
 
     /**
-     * Kirjoittaa asiakaslistan annetun nimiseen tiedostoon.
-     *
-     * @param asiakaslista lista asiakkaista
-     * @param tiedostonNimi kirjoitettavan tiedoston nimi
-     */
-    public static void kirjoitaAsiakkaat(ArrayList<Asiakas> asiakaslista, String tiedostonNimi) {
-        try (ObjectOutputStream oos =
-                     new ObjectOutputStream(
-                             new FileOutputStream(tiedostonNimi))) {
-            oos.writeObject(asiakaslista);
-        } catch (IOException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        }
-    }
-
-    /**
-     * Lukee asiakaslistan tiedostosta
-     *
-     * @param tiedostonNimi tiedoston nimi
-     * @return listan asiakkaita
-     */
-    public static ArrayList<Asiakas> lueAsiakkaat(String tiedostonNimi) {
-        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(tiedostonNimi))) {
-            ArrayList<Asiakas> alista = (ArrayList<Asiakas>) ois.readObject();
-            return alista;
-        } catch (IOException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        } catch (ClassNotFoundException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        }
-        return null;
-    }
-
-    /**
-     * Kirjoittaa tuotelistan annetun nimiseen tiedostoon.
-     *
-     * @param tuotelista    lista tuotteista
-     * @param tiedostonNimi kirjoitettavan tiedoston nimi
-     */
-    public static void kirjoitaTuotteet(ArrayList<Tuote> tuotelista, String tiedostonNimi) {
-        try (ObjectOutputStream oos =
-                     new ObjectOutputStream(
-                             new FileOutputStream(tiedostonNimi))) {
-            oos.writeObject(tuotelista);
-        } catch (IOException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        }
-    }
-
-    /**
-     * Lukee tuotelistan tiedostosta
-     *
-     * @param tiedostonNimi tiedoston nimi
-     * @return listan tuotteita
-     */
-    public static ArrayList<Tuote> lueTuotteet(String tiedostonNimi) {
-        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(tiedostonNimi))) {
-            ArrayList<Tuote> tlista = (ArrayList<Tuote>) ois.readObject();
-            return tlista;
-        } catch (IOException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        } catch (ClassNotFoundException e) {
-            // Tämä virhe tulee, jos luettu tieto ei ole yhteensopiva
-            // sen luokan kanssa, jonka tyyppiseksi se yritetään muuntaa
-            System.out.println("Tapahtui virhe: " + e);
-        }
-        return null;
-    }
-
-    /**
-     * Kirjoittaa myyjälistan annetun nimiseen tiedostoon.
-     *
-     * @param myyjalista    lista myyjistä
-     * @param tiedostonNimi kirjoitettavan tiedoston nimi
-     */
-    public static void kirjoitaMyyjat(ArrayList<Myyja> myyjalista, String tiedostonNimi) {
-        try (ObjectOutputStream oos =
-                     new ObjectOutputStream(
-                             new FileOutputStream(tiedostonNimi))) {
-            oos.writeObject(myyjalista);
-        } catch (IOException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        }
-    }
-
-    /**
-     * Lukee myyjälistan tiedostosta
-     *
-     * @param tiedostonNimi tiedoston nimi
-     * @return listan myyjiä
-     */
-    public static ArrayList<Myyja> lueMyyjat(String tiedostonNimi) {
-        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(tiedostonNimi))) {
-            ArrayList<Myyja> mlista = (ArrayList<Myyja>) ois.readObject();
-            return mlista;
-        } catch (IOException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        } catch (ClassNotFoundException e) {
-            System.out.println("Tapahtui virhe: " + e);
-        }
-        return null;
-    }
-
-    /**
-     * Kirjoittaa ostotapahtumalistan annetun nimiseen tiedostoon.
+     * Kirjoittaa listan Tyyppi-olioista annetun nimiseen tiedostoon.
      *
-     * @param tapahtumaLista lista ostotapahtumista
+     * @param lista lista Tyyppi-olioista
      * @param tiedostonNimi kirjoitettavan tiedoston nimi
      */
-    public static void kirjoitaTapahtumat(ArrayList<Ostotapahtuma> tapahtumaLista, String tiedostonNimi) {
+    public static <Tyyppi> void kirjoita(ArrayList<Tyyppi> lista, String tiedostonNimi) {
         try (ObjectOutputStream oos =
                      new ObjectOutputStream(
                              new FileOutputStream(tiedostonNimi))) {
-            oos.writeObject(tapahtumaLista);
+            oos.writeObject(lista);
         } catch (IOException e) {
             System.out.println("Tapahtui virhe: " + e);
         }
     }
 
     /**
-     * Lukee ostotapahtumalistan tiedostosta
+     * Lukee Tyyppi-olioista koostuvan listan tiedostosta
      *
      * @param tiedostonNimi tiedoston nimi
-     * @return listan ostotapahtumia
+     * @return listan Tyyppi-olioita
      */
-    public static ArrayList<Ostotapahtuma> lueTapahtumat(String tiedostonNimi) {
+    public static <Tyyppi> ArrayList<Tyyppi> lue(String tiedostonNimi) {
         try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(tiedostonNimi))) {
-            ArrayList<Ostotapahtuma> otlista = (ArrayList<Ostotapahtuma>) ois.readObject();
-            return otlista;
+            ArrayList<Tyyppi> lista = (ArrayList<Tyyppi>) ois.readObject();
+            return lista;
         } catch (IOException e) {
             System.out.println("Tapahtui virhe: " + e);
         } catch (ClassNotFoundException e) {
diff --git a/VerkkokauppaUI.java b/VerkkokauppaUI.java
new file mode 100644
index 0000000000000000000000000000000000000000..38e056443143987278f34d92bd7231749f0a0f46
--- /dev/null
+++ b/VerkkokauppaUI.java
@@ -0,0 +1,243 @@
+import java.util.Scanner;
+
+public class VerkkokauppaUI {
+    private Verkkokauppa verkkokauppa;
+    private Scanner lukija;
+
+    public static void main(String[] args) {
+        VerkkokauppaUI ui = new VerkkokauppaUI();
+        ui.aloita();
+    }
+
+    public VerkkokauppaUI() {
+        verkkokauppa = new Verkkokauppa();
+        verkkokauppa.lataa();
+        lukija = new Scanner(System.in);
+    }
+
+    public void aloita() {
+        int valinta = -1; // joku muu kuin 0
+        while (valinta != 0) {
+            tulostaMenu();
+            valinta = lueKokonaisluku(0, 4, "Anna valinta");
+            if (valinta == 1) {
+                asiakasMenu();
+            } else if (valinta == 2) {
+                tuoteMenu();
+            } else if (valinta == 3) {
+                myyjaMenu();
+            } else if (valinta == 4) {
+                ostotapahtumaMenu(); // ei vielä toteutettu...
+            }
+        }
+        verkkokauppa.tallenna();
+    }
+
+    private void asiakasMenu() {
+        int valinta = -1;
+        while (valinta != 0) {
+            System.out.println(verkkokauppa.listaaAsiakkaat());
+            System.out.println();
+            System.out.println("1. Lisää asiakas");
+            System.out.println("2. Poista asiakas");
+            System.out.println("3. Muuta kanta-asiakkaaksi");
+            System.out.println("0. Poistu");
+
+            valinta = lueKokonaisluku(0, 3, "Anna valinta");
+            if (valinta == 1) {
+                String asnro = lueMerkkijono("Asiakasnumero");
+                String nimi = lueMerkkijono("Nimi");
+                verkkokauppa.lisaaAsiakas(new Asiakas(asnro, nimi, 0));
+                System.out.println("Asiakas lisätty!");
+            } else if (valinta == 2) {
+                String asnro = lueMerkkijono("Asiakasnumero");
+                Asiakas as = verkkokauppa.annaAsiakas(asnro);
+                if (as != null) {
+                    verkkokauppa.poistaAsiakas(as);
+                    System.out.println("Asiakas poistettu!");
+                } else {
+                    System.out.println("Asiakasta ei löytynyt.");
+                }
+            } else if (valinta == 3) {
+                String asnro = lueMerkkijono("Asiakasnumero");
+                Asiakas as = verkkokauppa.annaAsiakas(asnro);
+                if (as != null) {
+                    KantaAsiakas ka = new KantaAsiakas(as.getAsiakasNumero(),
+                            as.getNimi(), as.getOstojaTehty(), 0);
+                    verkkokauppa.poistaAsiakas(as);
+                    verkkokauppa.lisaaAsiakas(ka);
+                    System.out.println("Muutettu!");
+                } else {
+                    System.out.println("Asiakasta ei löytynyt.");
+                }
+            }
+        }
+    }
+
+    private void tuoteMenu() {
+        int valinta = -1;
+        while (valinta != 0) {
+            System.out.println(verkkokauppa.listaaTuotteet());
+            System.out.println();
+            System.out.println("1. Lisää tuote");
+            System.out.println("2. Poista tuote");
+            System.out.println("3. Muuta saldoa");
+            System.out.println("4. Muuta hintaa");
+            System.out.println("0. Poistu");
+
+            valinta = lueKokonaisluku(0, 4,"Anna valinta");
+            if (valinta == 1) {
+                String nimi = lueMerkkijono("Nimi");
+                double hinta = lueDesimaaliluku(0, Tuote.MAKSIMIHINTA, "Anna hinta");
+                String virt = lueMerkkijono("Onko virtuaalinen tuote kyllä / ei");
+                if (virt.equals("kyllä")) {
+                    verkkokauppa.lisaaTuote(new VirtuaalinenTuote(nimi, hinta));
+                } else {
+                    int saldo = lueKokonaisluku(0, Tuote.MAKSIMISALDO, "Anna saldo");
+                    verkkokauppa.lisaaTuote(new Tuote(nimi, saldo, hinta));
+                }
+
+                System.out.println("Tuote lisätty!");
+            } else if (valinta == 2) {
+                String nimi = lueMerkkijono("Nimi");
+                Tuote tuote = verkkokauppa.annaTuote(nimi);
+                if (tuote != null) {
+                    verkkokauppa.poistaTuote(tuote);
+                    System.out.println("Tuote poistettu!");
+                } else {
+                    System.out.println("Tuotetta ei löytynyt.");
+                }
+            } else if (valinta == 3) {
+                String nimi = lueMerkkijono("Nimi");
+                Tuote tuote = verkkokauppa.annaTuote(nimi);
+                if (tuote != null) {
+                    int saldo = lueKokonaisluku(0, Tuote.MAKSIMISALDO, "Anna uusi saldo");
+                    tuote.setSaldo(saldo);
+                } else {
+                    System.out.println("Tuotetta ei löytynyt.");
+                }
+            } else if (valinta == 4) {
+                String nimi = lueMerkkijono("Nimi");
+                Tuote tuote = verkkokauppa.annaTuote(nimi);
+                if (tuote != null) {
+                    double hinta = lueDesimaaliluku(0, Tuote.MAKSIMIHINTA, "Anna uusi hinta");
+                    tuote.setHinta(hinta);
+                } else {
+                    System.out.println("Tuotetta ei löytynyt.");
+                }
+            }
+        }
+    }
+
+    private void myyjaMenu() {
+        int valinta = -1;
+        while (valinta != 0) {
+            System.out.println(verkkokauppa.listaaMyyjat());
+            System.out.println();
+            System.out.println("1. Lisää myyjä");
+            System.out.println("2. Poista myyjä");
+            System.out.println("0. Poistu");
+
+            valinta = lueKokonaisluku(0, 2, "Anna valinta");
+            if (valinta == 1) {
+                String tunniste = lueMerkkijono("Tunniste");
+                String nimi = lueMerkkijono("Nimi");
+                verkkokauppa.lisaaMyyja(new Myyja(tunniste, nimi, 0));
+                System.out.println("Myyjä lisätty!");
+            } else if (valinta == 2) {
+                String tunniste = lueMerkkijono("Tunniste");
+                Myyja m = verkkokauppa.annaMyyja(tunniste);
+                if (m != null) {
+                    verkkokauppa.poistaMyyja(m);
+                    System.out.println("Myyjä poistettu!");
+                } else {
+                    System.out.println("Myyjää ei löytynyt.");
+                }
+            }
+        }
+    }
+
+    /**
+     * TODO: Toteuta tämä demojen 2. tehtävänä - katso demosta tarkemmat ohjeet
+     */
+    private void ostotapahtumaMenu() {
+
+    }
+
+    private void tulostaMenu() {
+        System.out.println("1. Asiakkaat");
+        System.out.println("2. Tuotteet");
+        System.out.println("3. Myyjät");
+        System.out.println("4. Ostotapahtumat");
+        System.out.println("0. Poistu");
+    }
+
+
+    /**
+     * Lukee käyttäjältä syötteen ja palauttaa sen kokonaislukuna.
+     * Kokonaisluvun tulee olla annetun minimi ja maksimiarvon välissä.
+     *
+     * @param minimi  pienin sallittu arvo
+     * @param maksimi suurin sallittu arvo
+     * @param kehote käyttäjälle näytetty kehote
+     * @return käyttäjän syötteen kokonaislukuna
+     */
+    private int lueKokonaisluku(int minimi, int maksimi, String kehote) {
+        while (true) {
+            System.out.print(kehote + ": ");
+            try {
+                int arvo = Integer.parseInt(lukija.nextLine());
+                if (arvo >= minimi && arvo <= maksimi) {
+                    return arvo;
+                }
+                System.out.println("Arvon pitää olla väliltä " +
+                        minimi + " - " + maksimi);
+            } catch (NumberFormatException nfe) {
+                System.out.println("Anna arvo numerona!");
+            }
+        }
+    }
+
+    /**
+     * Lukee käyttäjältä syötteen ja palauttaa sen liukulukuna.
+     * Luvun tulee olla annetun minimi ja maksimiarvon välissä.
+     *
+     * @param minimi  pienin sallittu arvo
+     * @param maksimi suurin sallittu arvo
+     * @param kehote käyttäjälle näytetty kehote
+     * @return käyttäjän syötteen liukulukuna
+     */
+    private double lueDesimaaliluku(double minimi, double maksimi, String kehote) {
+        while (true) {
+            System.out.print(kehote + ": ");
+            try {
+                double arvo = Double.parseDouble(lukija.nextLine());
+                if (arvo >= minimi && arvo <= maksimi) {
+                    return arvo;
+                }
+                System.out.println("Luvun pitää olla väliltä " +
+                        minimi + " - " + maksimi);
+            } catch (NumberFormatException nfe) {
+                System.out.println("Anna luku numerona!");
+            }
+        }
+    }
+
+    /**
+     * Apumetodi, joka näyttää käyttäjälle annetun kehotteen ja lukee
+     * sitten tältä merkkijonon. Annettu jono ei voi olla tyhjä.
+     *
+     * @param kehote käyttäjälle näytettävä kehote
+     * @return käyttäjän syöttämän ei-tyhjän merkkijonon
+     */
+    private String lueMerkkijono(String kehote) {
+        while (true) {
+            System.out.print(kehote + ": ");
+            String arvo = lukija.nextLine();
+            if (!arvo.equals("")) {
+                return arvo;
+            }
+        }
+    }
+
+}