diff --git a/foreksempel/src/main/java/of5_2/Ovingsforelesning_5.2.pptx.pdf b/foreksempel/src/main/java/of5_2/Ovingsforelesning_5.2.pptx.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..ee514878226a712fe76c5a1678abaa57ecd44ea9
Binary files /dev/null and b/foreksempel/src/main/java/of5_2/Ovingsforelesning_5.2.pptx.pdf differ
diff --git a/foreksempel/src/main/java/of5_2/lf/Animal.java b/foreksempel/src/main/java/of5_2/lf/Animal.java
new file mode 100644
index 0000000000000000000000000000000000000000..4e5a58b4d10b41843c1f0c9d7cd611022edfe5d4
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/Animal.java
@@ -0,0 +1,12 @@
+package of5_2.lf;
+
+public interface Animal extends Comparable<Animal> {
+    
+    String getName();
+
+    int getAge();
+
+    String makeSound();
+
+}
+
diff --git a/foreksempel/src/main/java/of5_2/lf/Chicken.java b/foreksempel/src/main/java/of5_2/lf/Chicken.java
new file mode 100644
index 0000000000000000000000000000000000000000..5892792158b96c87db9b1fe8beada47018dc2d83
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/Chicken.java
@@ -0,0 +1,34 @@
+package of5_2.lf;
+
+public class Chicken implements Animal{
+    private int age;
+    private String name;
+
+    public Chicken(String name, int age) {
+        this.name = name;
+        this.age = age;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public int getAge() {
+    return age;
+    
+    }
+
+    @Override
+    public String makeSound() {
+        return name + " sier klukk!";
+    }
+
+    @Override
+    public int compareTo(Animal other) {
+        return this.getAge() - other.getAge();
+    }
+
+    
+}
\ No newline at end of file
diff --git a/foreksempel/src/main/java/of5_2/lf/Dog.java b/foreksempel/src/main/java/of5_2/lf/Dog.java
new file mode 100644
index 0000000000000000000000000000000000000000..73bf41d32a04882471a10f5cf552a276d743567e
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/Dog.java
@@ -0,0 +1,35 @@
+package of5_2.lf;
+
+public class Dog implements Animal {
+    
+    private int age;
+    private String name;
+
+    public Dog(String name, int age) {
+        this.name = name;
+        this.age = age;
+    }
+
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Override
+    public int getAge() {
+    return age;
+    
+    }
+
+    @Override
+    public String makeSound() {
+        return name + " sier bjeff!";
+    }
+
+    @Override
+    public int compareTo(Animal other) {
+        return this.getAge() - other.getAge();
+    }
+
+    
+}
diff --git a/foreksempel/src/main/java/of5_2/lf/DogPredicate.java b/foreksempel/src/main/java/of5_2/lf/DogPredicate.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6ac6d0937ed110c9e14f297f15c2c95a1204d62
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/DogPredicate.java
@@ -0,0 +1,13 @@
+package of5_2.lf;
+
+import java.util.function.Predicate;
+
+public class DogPredicate implements Predicate<Animal>{
+
+    @Override
+    public boolean test(Animal t) {
+        return t instanceof Dog;
+    }
+
+    
+}
diff --git a/foreksempel/src/main/java/of5_2/lf/Farm.java b/foreksempel/src/main/java/of5_2/lf/Farm.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc5efba40db1f96c7341c90567f550555cb4070d
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/Farm.java
@@ -0,0 +1,145 @@
+package of5_2.lf;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class Farm implements Iterable<Animal>{
+
+    private List<Animal> animals = new ArrayList<>();
+
+    public void addAnimal(Animal animal){
+        if(animals.contains(animal)){
+            throw new IllegalArgumentException("Animal already added");
+
+        }
+        animals.add(animal);
+    }
+
+    
+    public List<Animal> getAnimals(){
+        return new ArrayList<>(animals);
+    }
+
+    public int numberOfAnimals(){
+        return this.animals.size();
+    }
+
+    public Animal getAnimal(int index){
+        return animals.get(index);
+    }
+
+    @Override
+    public Iterator<Animal> iterator() {
+        return this.animals.iterator();
+    }
+
+    public List<String> getAnimalNames(){
+        return this.animals.stream()
+            .map((animal) -> animal
+            .getName())
+            .distinct()
+            .toList();
+    }
+
+    public static void main(String[] args) {
+        Dog Ludo = new Dog("Ludo", 2);
+        Chicken Albert = new Chicken("Albert", 1);
+        Dog Ollie = new Dog("Ollie", 6);
+        Dog Buddy = new Dog("Buddy", 8);
+        Chicken Ringo = new Chicken("Ringo", 6);
+        Chicken Kjell = new Chicken("Kjell", 5);
+
+        List<Animal> animals = new ArrayList<>(List.of(
+            Ludo, Albert, Ollie, Buddy, Ringo, Kjell
+            ));
+
+        Farm farm = new Farm();
+        farm.addAnimal(animals.get(0));
+        farm.addAnimal(animals.get(1));
+        farm.addAnimal(animals.get(2));
+        farm.addAnimal(animals.get(3));
+        farm.addAnimal(animals.get(4));
+        farm.addAnimal(animals.get(5));
+
+
+        //Oppgave 1
+        /* Collections.sort(animals);
+
+        for (Animal animal : animals){
+            System.out.println(""+animal.getName()+" "+ animal.getAge() + " " + animal.makeSound());
+
+        } */
+
+
+        /* 
+
+        //Oppgave 2
+        for (Animal animal : farm){
+            System.out.println(animal.makeSound());
+        } */
+
+        //Oppgave 3
+        /* Iterator<Animal> iterator  = new YoungAnimalsIterator(farm);
+        while(iterator.hasNext()){
+            System.out.println(iterator.next().makeSound());
+
+        } */
+
+
+        //Oppgave 4
+        /* Iterator<Animal> iterator = new FilterAnimalsIterator(farm, new DogPredicate());
+        while (iterator.hasNext()) {
+            System.out.println(iterator.next().makeSound());
+        } */
+
+
+        //Oppgave 5
+        /* Iterator<Animal> iterator = new FilterAnimalsIterator(farm, (p -> p.getAge()<=2));
+        while (iterator.hasNext()) {
+            System.out.println(iterator.next().makeSound());
+        } */
+
+        //Oppgave 6
+        /* Collections.sort(animals, (animal1, animal2) -> animal1.getName().compareTo(animal2.getName()));
+        for (Animal animal : animals){
+            System.out.println(animal.makeSound());
+        } */
+
+        //Oppgave 7
+        /* animals.add(new Dog("Ludo",8)); */
+
+        //Oppgave 8
+        /* Iterator<Animal> iterator = new FilterAnimalsIterator(farm, (p -> p.getAge()<=2));
+        while (iterator.hasNext()) {
+            System.out.println(iterator.next().makeSound());
+
+        farm.getAnimals().stream()
+            .filter(new DogPredicate())
+            .forEach(animal -> {
+                System.out.println(animal.makeSound());}
+            ); */
+        
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+    }
+
+}
diff --git a/foreksempel/src/main/java/of5_2/lf/FilterAnimalsIterator.java b/foreksempel/src/main/java/of5_2/lf/FilterAnimalsIterator.java
new file mode 100644
index 0000000000000000000000000000000000000000..46ea83f434c003aed3bb0b739fd87df68201ff46
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/FilterAnimalsIterator.java
@@ -0,0 +1,38 @@
+package of5_2.lf;
+
+import java.util.Iterator;
+import java.util.function.Predicate;
+
+public class FilterAnimalsIterator implements Iterator<Animal> {
+    private int index = 0;
+    private Farm farm;
+    private Predicate<Animal> animalPredicate;
+
+    public FilterAnimalsIterator(Farm farm, Predicate<Animal> animalPredicate){
+        this.animalPredicate = animalPredicate;
+        this.farm = farm;
+
+    }
+
+    @Override
+    public boolean hasNext() {
+        while(index<farm.numberOfAnimals()){
+            if(animalPredicate.test(farm.getAnimal(index))){
+                return true;
+            }
+            else{
+                index++;
+            }
+            
+        }
+        return false;
+    }
+
+    @Override
+    public Animal next() {
+        if(!hasNext()){
+            throw new IllegalArgumentException("No more animals in the farm");
+        }
+        return farm.getAnimal(index++);
+    }
+}
diff --git a/foreksempel/src/main/java/of5_2/lf/YoungAnimalPredicate.java b/foreksempel/src/main/java/of5_2/lf/YoungAnimalPredicate.java
new file mode 100644
index 0000000000000000000000000000000000000000..caf3de961a22c520d67fb922a1440ab6d155466f
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/YoungAnimalPredicate.java
@@ -0,0 +1,12 @@
+package of5_2.lf;
+
+import java.util.function.Predicate;
+
+public class YoungAnimalPredicate implements Predicate<Animal> {
+
+    @Override
+    public boolean test(Animal t) {
+        return t.getAge() <= 2;
+    }
+    
+}
diff --git a/foreksempel/src/main/java/of5_2/lf/YoungAnimalsIterator.java b/foreksempel/src/main/java/of5_2/lf/YoungAnimalsIterator.java
new file mode 100644
index 0000000000000000000000000000000000000000..6a3a2d8ae69dc596b36c01866a9895087104b3c0
--- /dev/null
+++ b/foreksempel/src/main/java/of5_2/lf/YoungAnimalsIterator.java
@@ -0,0 +1,39 @@
+package of5_2.lf;
+
+import java.util.Iterator;
+
+public class YoungAnimalsIterator implements Iterator<Animal> {
+
+    private int index = 0;
+    private Farm farm;
+
+    public YoungAnimalsIterator(Farm farm){
+        this.farm = farm;
+
+    }
+
+    @Override
+    public boolean hasNext() {
+        while(index<farm.numberOfAnimals()){
+            if(farm.getAnimal(index).getAge()<=2){
+                return true;
+            }
+            else{
+                index++;
+            }
+            
+        }
+        return false;
+    }
+
+    @Override
+    public Animal next() {
+        if(!hasNext()){
+            throw new IllegalArgumentException("No more animals in the farm");
+        }
+        return farm.getAnimal(index++);
+    }
+
+
+    
+}
diff --git a/lf/src/main/java/oving3/CardDeck.java b/lf/src/main/java/oving3/CardDeck.java
new file mode 100644
index 0000000000000000000000000000000000000000..be0541498abcdec3f0364327c657e65ca19aa1cd
--- /dev/null
+++ b/lf/src/main/java/oving3/CardDeck.java
@@ -0,0 +1,50 @@
+package oving3;
+
+import java.util.ArrayList;
+
+public class CardDeck {
+
+	// List to hold Card objects
+	private ArrayList<Card> cards;
+
+	public CardDeck(int suitSize) {
+		if (suitSize < 0 || suitSize > 13) {
+			throw new IllegalArgumentException("Illegal suit size " + suitSize);
+		}
+
+		this.cards = new ArrayList<Card>();
+
+		for (char suit : Card.SUITS.toCharArray()) {
+			for (int face = 1; face <= suitSize; face++) {
+				Card card = new Card(suit, face);
+				cards.add(card);
+			}
+		}
+	}
+
+	public int getCardCount() {
+		return this.cards.size();
+	}
+
+	public Card getCard(int i) {
+		if (i < 0 || i >= this.getCardCount()) {
+			throw new IllegalArgumentException(
+					String.format("%s is an illegal card index, when the size of the deck is %s", i, getCardCount()));
+		}
+
+		return cards.get(i);
+	}
+
+	public void shufflePerfectly() {
+		int halfSize = cards.size() / 2;
+		for (int i = 0; i < halfSize; i++) {
+			Card card = cards.remove(halfSize + i);
+			cards.add(i * 2 + 1, card);
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "[Deck " + cards.toString().substring(1);
+	}
+}
diff --git a/lf/src/main/java/oving3/Nim.java b/lf/src/main/java/oving3/Nim.java
new file mode 100644
index 0000000000000000000000000000000000000000..472c19adb43aeff758a2fa767f5f359306ee9545
--- /dev/null
+++ b/lf/src/main/java/oving3/Nim.java
@@ -0,0 +1,43 @@
+package oving3;
+
+public class Nim {
+
+	private int[] piles;
+
+	public Nim() {
+		this(10);
+	}
+
+	public Nim(int pileSize) {
+		this.piles = new int[] { pileSize, pileSize, pileSize };
+	}
+
+	public void removePieces(int number, int targetPile) {
+		if (this.isGameOver()) {
+			throw new IllegalStateException("Cannot remove pieces when game is over");
+		}
+
+		if (!this.isValidMove(number, targetPile)) {
+			throw new IllegalArgumentException("Move is not valid");
+		}
+
+		piles[targetPile] -= number;
+	}
+
+	public boolean isValidMove(int number, int targetPile) {
+		return number > 0 && this.getPile(targetPile) >= number && !this.isGameOver();
+	}
+
+	public boolean isGameOver() {
+		return this.getPile(0) == 0 || this.getPile(1) == 0 || this.getPile(2) == 0;
+	}
+
+	public int getPile(int targetPile) {
+		return this.piles[targetPile];
+	}
+
+	@Override
+	public String toString() {
+		return String.format("Piles: %d, %d, %d", piles[0], piles[1], piles[2]);
+	}
+}
diff --git a/lf/src/main/java/oving3/RPNCalc.java b/lf/src/main/java/oving3/RPNCalc.java
new file mode 100644
index 0000000000000000000000000000000000000000..414aff6ca18fd0c3c7cd10f360f57e30e01763c5
--- /dev/null
+++ b/lf/src/main/java/oving3/RPNCalc.java
@@ -0,0 +1,143 @@
+package oving3;
+
+import java.util.Stack;
+
+public class RPNCalc {
+
+	private Stack<Double> operandStack;
+
+	public RPNCalc() {
+		operandStack = new Stack<Double>();
+	}
+
+	public void push(double value) {
+		operandStack.push(value);
+	}
+
+	public int getSize() {
+		return operandStack.size();
+	}
+
+	public double peek(int n) {
+		if (n < 0 || operandStack.size() <= n) {
+			return Double.NaN;
+		}
+
+		return operandStack.get(operandStack.size() - n - 1);
+	}
+
+	public double pop() {
+		return this.pop(Double.NaN);
+	}
+
+	public double pop(double defaultValue) {
+		if (operandStack.isEmpty()) {
+			return defaultValue;
+		}
+
+		return operandStack.pop();
+	}
+
+	// perform the operation denoted by op
+	// each operation pops and pushes values off and onto the operand stack,
+	public void performOperation(char op) {
+		double d1, d2;
+		switch (op) {
+			case '+':
+				// pop two operands and push the sum, missing values default to 0.0
+				d1 = pop(0.0);
+				d2 = pop(0.0);
+				push(d2 + d1);
+				break;
+			case '-':
+				// pop two operands and push the difference, missing values default to 0.0
+				d1 = pop(0.0);
+				d2 = pop(0.0);
+				push(d2 - d1);
+				break;
+			case '*':
+				// pop two operands and push the product, missing values default to 1.0
+				d1 = pop(1.0);
+				d2 = pop(1.0);
+				push(d2 * d1);
+				break;
+			case '/':
+				// pop two operands and push the quotient, missing values default to 1.0
+				d1 = pop(1.0);
+				d2 = pop(1.0);
+				push(d2 / d1);
+				break;
+			// dup
+			case ',':
+				d1 = pop(0.0);
+				// push back twice
+				push(d1);
+				push(d1);
+				break;
+			// pop
+			case '.':
+				// remove the topmost value
+				pop(0.0);
+				break;
+			// swap
+			case '~':
+				// swap the two topmost values, by popping them and pushing them in reverse
+				// order
+				d1 = pop(0.0);
+				d2 = pop(0.0);
+				push(d1);
+				push(d2);
+				break;
+			// extra operators
+			// remainder
+			case '%':
+				d1 = pop(1.0);
+				d2 = pop(1.0);
+				push(d2 % d1);
+				break;
+			// absolute
+			case '|':
+				push(Math.abs(pop(0.0)));
+				break;
+			// square root
+			case 'v':
+				push(Math.sqrt(pop(1.0)));
+				break;
+			// power of
+			case '^':
+				d1 = pop(1.0);
+				d2 = pop(1.0);
+				push(Math.pow(d2, d1));
+				break;
+			// floor
+			case '_':
+				double d = pop(0.0);
+				push(Math.floor(d));
+				break;
+			// compare
+			case '=':
+				d1 = pop(1.0);
+				d2 = pop(1.0);
+				push(Double.compare(d2, d1));
+				break;
+			// signum
+			case '?':
+				push(Math.signum(pop(0.0)));
+				break;
+			// pi
+			case 'p':
+			case 'π':
+				push(Math.PI);
+				break;
+			// e
+			case 'e':
+				push(Math.exp(1.0));
+				break;
+		}
+	}
+
+	@Override
+	public String toString() {
+		return operandStack.toString();
+	}
+}
diff --git a/lf/src/main/java/oving3/debugging/CoffeeCup.java b/lf/src/main/java/oving3/debugging/CoffeeCup.java
new file mode 100644
index 0000000000000000000000000000000000000000..c45ac51c99c87972a3fddf64b58ae74f0302cce1
--- /dev/null
+++ b/lf/src/main/java/oving3/debugging/CoffeeCup.java
@@ -0,0 +1,69 @@
+package oving3.debugging;
+
+public class CoffeeCup {
+
+	private double capacity;
+	private double currentVolume;
+
+	public CoffeeCup() {
+		this.capacity = 0.0;
+		this.currentVolume = 0.0;
+	}
+
+	public CoffeeCup(double capacity, double currentVolume) {
+		if (isValidCapacity(capacity)) {
+			this.capacity = capacity;
+		} else {
+			throw new IllegalArgumentException("Illegal capacity given.");
+		}
+		if (isValidVolume(currentVolume)) {
+			this.currentVolume = currentVolume;
+		} else {
+			throw new IllegalArgumentException("Illegal volume given.");
+		}
+	}
+
+	private boolean isValidCapacity(double capacity) {
+		if (capacity >= 0.0) {
+			return true;
+		}
+		return false;
+	}
+
+	public void increaseCupSize(double biggerCapacity) {
+		if (isValidCapacity(biggerCapacity)) {
+			this.capacity += biggerCapacity;
+		}
+	}
+
+	private boolean isValidVolume(double volume) {
+		if (volume > this.capacity || volume < 0.0) {
+			return false;
+		}
+		return true;
+	}
+
+	private boolean canDrink(double volume) {
+		if (this.currentVolume >= volume) {
+			return true;
+		}
+		return false;
+	}
+
+	public void drinkCoffee(double volume) {
+		if (isValidVolume(volume) && canDrink(volume)) {
+			this.currentVolume -= volume;
+		} else {
+			throw new IllegalArgumentException("You can't drink that much coffee!");
+		}
+	}
+
+	public void fillCoffee(double volume) {
+		if (isValidVolume(this.currentVolume + volume)) {
+			this.currentVolume += volume;
+		} else {
+			throw new IllegalArgumentException("You just poured coffee all over the table. Good job.");
+		}
+	}
+
+}
diff --git a/lf/src/main/java/oving3/debugging/CoffeeCupProgram.java b/lf/src/main/java/oving3/debugging/CoffeeCupProgram.java
new file mode 100644
index 0000000000000000000000000000000000000000..4546eca04972d5df6accd82cb1332e2bf46708b7
--- /dev/null
+++ b/lf/src/main/java/oving3/debugging/CoffeeCupProgram.java
@@ -0,0 +1,58 @@
+package oving3.debugging;
+
+import java.util.Random;
+
+public class CoffeeCupProgram {
+
+	private CoffeeCup cup;
+	private Random r;
+
+	public void init() {
+		cup = new CoffeeCup();
+		r = new Random(123456789L);
+	}
+
+	public void run() {
+		part1();
+		part2();
+	}
+
+	private void part1() {
+		cup.increaseCupSize(40.0);
+		cup.fillCoffee(20.5);
+		cup.drinkCoffee(Math.floor(r.nextDouble() * 20.5));
+		cup.fillCoffee(32.5);
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 38.9));
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 42));
+		cup.increaseCupSize(17);
+		cup.drinkCoffee(40);
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 42));
+		cup.drinkCoffee(Math.floor(r.nextDouble() * 20.5));
+		cup.fillCoffee(32.5);
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 38.9));
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 42));
+		cup.increaseCupSize(17);
+	}
+
+	private void part2() {
+		cup = new CoffeeCup(40.0, 20.5);
+		r = new Random(987654321L);
+		cup.drinkCoffee(Math.floor(r.nextDouble() * 20.5));
+		cup.fillCoffee(Math.floor(r.nextDouble() * 30));
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 38.9));
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 42));
+		cup.increaseCupSize(Math.floor(r.nextDouble() * 26));
+		cup.fillCoffee(Math.ceil(r.nextDouble() * 59));
+		cup.drinkCoffee(Math.ceil(r.nextDouble() * 42));
+		cup.increaseCupSize(Math.floor(r.nextDouble() * 35));
+		cup.fillCoffee(Math.floor(r.nextDouble() * 30));
+		cup.increaseCupSize(Math.floor(r.nextDouble() * 26));
+	}
+
+	public static void main(String[] args) {
+		CoffeeCupProgram program = new CoffeeCupProgram();
+		program.init();
+		program.run();
+	}
+
+}
diff --git a/lf/src/main/java/oving4/Card.java b/lf/src/main/java/oving4/Card.java
new file mode 100644
index 0000000000000000000000000000000000000000..aa44ce5eb889a31a47ba2faf4bcdd3519f527a43
--- /dev/null
+++ b/lf/src/main/java/oving4/Card.java
@@ -0,0 +1,41 @@
+package oving4;
+
+public class Card {
+
+	// the suit (farge), one of the values 'S' (spades), 'H' (hearts), 'D'
+	// (diamonds) and 'C' (clubs)
+	private char suit;
+	// the value, 1 for the ace, 2 - 10, 11 (knight), 12 (queen) and 13 (king). -1
+	// is invalid
+	private int face = -1;
+
+	// the set of suits in decreasing order
+	public final static String SUITS = "SHDC";
+
+	public Card(char suit, int face) {
+		if (SUITS.indexOf(suit) < 0) {
+			throw new IllegalArgumentException("Illegal suit: " + suit);
+		}
+		if (face < 1 || face > 13) {
+			throw new IllegalArgumentException("Illegal face: " + face);
+		}
+		this.suit = suit;
+		this.face = face;
+	}
+
+	/*
+	 * Returns suit and face as a string
+	 * E.g. Ace of spades is S1 and king of clubs is C13
+	 */
+	public String toString() {
+		return String.valueOf(suit) + face;
+	}
+
+	public char getSuit() {
+		return this.suit;
+	}
+
+	public int getFace() {
+		return this.face;
+	}
+}
diff --git a/lf/src/main/java/oving4/CardDeck.java b/lf/src/main/java/oving4/CardDeck.java
new file mode 100644
index 0000000000000000000000000000000000000000..dc29d0969af7aa249346ae3ab5854e75f296165e
--- /dev/null
+++ b/lf/src/main/java/oving4/CardDeck.java
@@ -0,0 +1,50 @@
+package oving4;
+
+import java.util.ArrayList;
+
+public class CardDeck {
+
+	// array to hold Card objects, filled in the constructor
+	private ArrayList<Card> cards;
+
+	public CardDeck(int suitSize) {
+		cards = new ArrayList<Card>();
+		for (int i = 0; i < Card.SUITS.length(); i++) {
+			for (int face = 1; face <= suitSize; face++) {
+				Card card = new Card(Card.SUITS.charAt(i), face);
+				cards.add(card);
+			}
+		}
+	}
+
+	@Override
+	public String toString() {
+		return "[Deck " + cards.toString().substring(1);
+	}
+
+	public void deal(CardHand hand, int handSize) {
+		for (int i = 0; i < handSize; i++) {
+			hand.addCard(cards.remove(cards.size() - 1));
+		}
+	}
+
+	public int getCardCount() {
+		return cards.size();
+	}
+
+	public Card getCard(int i) {
+		if (i < 0 || i >= getCardCount()) {
+			throw new IllegalArgumentException(
+					String.format("%s is an illegal card index, when the size of the deck is %s", i, getCardCount()));
+		}
+		return cards.get(i);
+	}
+
+	public void shufflePerfectly() {
+		int halfSize = cards.size() / 2;
+		for (int i = 0; i < halfSize; i++) {
+			Card card = cards.remove(halfSize + i);
+			cards.add(i * 2 + 1, card);
+		}
+	}
+}
diff --git a/lf/src/main/java/oving4/CardHand.java b/lf/src/main/java/oving4/CardHand.java
new file mode 100644
index 0000000000000000000000000000000000000000..716773f0e50ec8c5f5f3ff864c4c1831bbe3ddd9
--- /dev/null
+++ b/lf/src/main/java/oving4/CardHand.java
@@ -0,0 +1,38 @@
+package oving4;
+
+import java.util.ArrayList;
+
+public class CardHand {
+
+	// array to hold Card objects, filled in the constructor
+	private ArrayList<Card> cards;
+
+	public CardHand() {
+		cards = new ArrayList<Card>();
+	}
+
+	@Override
+	public String toString() {
+		return "[Hand " + cards.toString().substring(1);
+	}
+
+	public void addCard(Card card) {
+		this.cards.add(card);
+	}
+
+	public int getCardCount() {
+		return cards.size();
+	}
+
+	public Card getCard(int i) {
+		if (i < 0 || i >= getCardCount()) {
+			throw new IllegalArgumentException(
+					String.format("%s is an illegal card index, when the size of the hand is %s", i, getCardCount()));
+		}
+		return cards.get(i);
+	}
+
+	public Card play(int i) {
+		return cards.remove(i);
+	}
+}