summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitignore6
-rw-r--r--LICENSE1
-rw-r--r--README.rst37
-rw-r--r--java/alist.txt13
-rw-r--r--java/buildall4
-rw-r--r--java/code/AddTwoNumbers.java81
-rw-r--r--java/code/ArraySearch.java130
-rw-r--r--java/code/ArraySort.java113
-rw-r--r--java/code/BankAccountExample.java155
-rw-r--r--java/code/ComplexCalculations.java43
-rw-r--r--java/code/ConeCalculations.java55
-rw-r--r--java/code/CylinderCalculations.java52
-rw-r--r--java/code/FindNumberInArray.java72
-rw-r--r--java/code/MatrixOperations.java172
-rw-r--r--java/code/SingletonExample.java23
-rw-r--r--java/code/StaticExecution.java30
-rw-r--r--java/code/StringOperations.java112
-rw-r--r--java/code/StudentsArray.java91
-rwxr-xr-xjava/dbld6
-rw-r--r--java/index.typ93
-rwxr-xr-xjava/jbld5
-rw-r--r--java/output/AddTwoNumbers.typ35
-rw-r--r--java/output/ArraySearch.typ94
-rw-r--r--java/output/ArraySort.typ59
-rw-r--r--java/output/CylinderCalculations.typ16
-rw-r--r--java/output/MatrixOperations.typ132
-rw-r--r--java/output/SingletonExample.typ9
-rw-r--r--java/output/StaticExecution.typ10
-rw-r--r--java/output/StringOperations.typ76
-rw-r--r--java/state.sql15
-rw-r--r--java/template.typ100
-rw-r--r--java/text/AddTwoNumbers.typ44
-rw-r--r--java/text/ArraySearch.typ44
-rw-r--r--java/text/ArraySort.typ30
-rw-r--r--java/text/ComplexCalculations.typ31
-rw-r--r--java/text/CylinderCalculations.typ34
-rw-r--r--java/text/MatrixOperations.typ47
-rw-r--r--java/text/StaticExecution.typ29
-rw-r--r--java/text/StringOperations.typ45
-rw-r--r--java/vendor/Java.sublime-syntax1246
-rw-r--r--java/vendor/gr.tmTheme566
-rwxr-xr-xjava/wltd5
42 files changed, 3945 insertions, 16 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0c74e12
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,6 @@
+*/docs
+*/docs/**
+java/build/**
+*.class
+*.pyc*
+*~
diff --git a/LICENSE b/LICENSE
index 3a2384c..5f97bae 100644
--- a/LICENSE
+++ b/LICENSE
@@ -3,3 +3,4 @@ Copyright 2023 by smlckz
 Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
 
 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
diff --git a/README.rst b/README.rst
index 959117f..7681316 100644
--- a/README.rst
+++ b/README.rst
@@ -1,21 +1,26 @@
 zadania
 =======
 
-Programming assignments for fifth semester of college.
-
-:Languages: Java, Python.
-:Papers:
-  - Core courses
-    + Object-oriented programming
-      
-      Using Java.
-    + Database Management System
-      
-      Using MySQL and PHP.
-  - Discipline-specific electives
-    + Digital Image Processing
-      
-      Using OpenCV in Python.
-    + Programming with Python
+大学第五学期的编程作业。
 
+Papers
+------
+
+- Core courses
+
+  + Database Management System
+
+    CC-11: RDBMS lab using MySQL and PHP.
+  + Object-oriented programming
+
+    CC-12: OOP lab Using Java.
+
+- Discipline-specific electives
+
+  + Digital Image Processing
+
+    DSE-A-1: DIP lab based on OpenCV in Python.
+  + Programming with Python
+
+    DSE-B-2: Python 3 Programming Lab
 
diff --git a/java/alist.txt b/java/alist.txt
new file mode 100644
index 0000000..6e11a63
--- /dev/null
+++ b/java/alist.txt
@@ -0,0 +1,13 @@
+ArraySearch #
+ArraySort #
+StringOperations #
+MatrixOperations #
+AddTwoNumbers #
+CylinderCalculations #
+ComplexCalculations
+FindNumberInArray 
+StaticExecution
+SingletonExample 
+StudentsArray
+BankAccountExample
+
diff --git a/java/buildall b/java/buildall
new file mode 100644
index 0000000..7cdd0c0
--- /dev/null
+++ b/java/buildall
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+awk '$3 == "#" { printf("#include(\"text/%s.typ\")\n", $2) }' alist.txt > all.typ
+typst compile --root $PWD all.typ a/all.pdf
diff --git a/java/code/AddTwoNumbers.java b/java/code/AddTwoNumbers.java
new file mode 100644
index 0000000..3c1b3e8
--- /dev/null
+++ b/java/code/AddTwoNumbers.java
@@ -0,0 +1,81 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Scanner;
+import java.util.InputMismatchException;
+
+class Number {
+    private double value;
+    Number(double n) {
+        value = n;
+    }
+    double valueOf() {
+        return value;
+    }
+}
+
+class ArithmeticOperations {
+    static Number add(Number a, Number b) {
+        return new Number(a.valueOf() + b.valueOf());
+    }
+}
+
+class AddTwoNumbers {
+    static void process(double a, double b) {
+        Number n1 = new Number(a), n2 = new Number(b);
+        System.out.println(n1.valueOf() + " + " + n2.valueOf() + " = " +
+            ArithmeticOperations.add(n1, n2).valueOf());
+    }
+}
+
+class AddTwoNumbersCLI extends AddTwoNumbers {
+    public static void main(String args[]) {
+        if (args.length != 2) {
+            System.err.println("Usage: AddTwoNumbersCLI first-number second-number");
+            System.exit(1);
+        }
+        try {
+            System.out.println("Taking input from CLI arguments:");
+            var v1 = Double.parseDouble(args[0]);
+            var v2 = Double.parseDouble(args[1]);
+            process(v1, v2);
+        } catch (NumberFormatException e) {
+            System.err.println("Invalid numbers");
+        }
+    }
+}
+
+class AddTwoNumbersScan extends AddTwoNumbers {
+    public static void main(String args[]) {
+        try {
+            System.out.println("Taking input using java.util.Scanner:");
+            var sc = new Scanner(System.in);
+            System.out.print("Enter first number: ");
+            var v1 = sc.nextDouble();
+            System.out.print("Enter second number: ");
+            var v2 = sc.nextDouble();
+            process(v1, v2);
+        } catch (InputMismatchException e) {
+            System.err.println("Invalid numbers");
+        }
+    }
+}
+
+class AddTwoNumbersBuf extends AddTwoNumbers {
+    public static void main(String args[]) {
+        try {
+            System.out.println("Taking input using java.io.BufferedReader:");
+            var r = new BufferedReader(new InputStreamReader(System.in));
+            System.out.print("Enter first number: ");
+            var v1 = Double.parseDouble(r.readLine());
+            System.out.print("Enter second number: ");
+            var v2 = Double.parseDouble(r.readLine());
+            process(v1, v2);
+        } catch (NumberFormatException e) {
+            System.err.println("Invalid numbers");
+        } catch (IOException e) {
+            System.err.println("I/O error occured while reading input.");
+        }
+    }
+}
+
diff --git a/java/code/ArraySearch.java b/java/code/ArraySearch.java
new file mode 100644
index 0000000..a9fab5e
--- /dev/null
+++ b/java/code/ArraySearch.java
@@ -0,0 +1,130 @@
+import java.util.Arrays;
+import java.util.Scanner;
+import java.util.InputMismatchException;
+import java.util.function.BiFunction;
+
+class Array {
+    private double[] arr;
+    Array() throws Exception {
+        takeInput();
+    }
+    void takeInput() throws Exception {
+        Scanner sc = new Scanner(System.in);
+        System.out.print("Enter the length: ");
+        int size = sc.nextInt();
+        if (size < 0)
+            throw new Exception("Array length can not be negative");
+        arr = new double[size];
+        System.out.print("Enter the array elements: ");
+        for (int i = 0; i < size; i++)
+            arr[i] = sc.nextDouble();
+    }
+    void display() {
+        System.out.print("The array elements are:");
+        for (int i = 0; i < arr.length; i++)
+            System.out.print(" " + arr[i]);
+        System.out.println();
+    }
+    double get(int i) throws IndexOutOfBoundsException {
+        return arr[i];
+    }
+    void set(int i, double val) throws IndexOutOfBoundsException {
+        arr[i] = val;
+    }
+    void sort() {
+        Arrays.sort(arr);
+    }
+    int size() { return arr.length; }
+}
+
+class ArrayOperations {
+    static int linearSearch(Array arr, double item) {
+        int size = arr.size();
+        for (int i = 0; i < size; i++) {
+            if (arr.get(i) == item)
+                return i;
+        }
+        return -1;
+    }
+    static int binarySearch(Array arr, double item) {
+        int size = arr.size();
+        int leftIndex = 0, rightIndex = size - 1;
+        while (leftIndex <= rightIndex) {
+            int midIndex = leftIndex + (rightIndex - leftIndex) / 2;
+            double midValue = arr.get(midIndex);
+            if (item == midValue) {
+                return midIndex;
+            } else if (item < midValue) {
+                rightIndex = midIndex - 1;
+            } else {
+                leftIndex = midIndex + 1;
+            }
+        }
+        return -1;
+    }
+}
+
+class ArraySearch {
+    static void menu() {
+        System.out.println(
+            "Menu:\n" +
+            " 1. Re-enter array\n" +
+            " 2. Display array elements\n" +
+            " 3. Perform linear search\n" +
+            " 4. Perform binary search\n" +
+            " 5. Exit\n");
+    }
+    static void performSearch(Scanner sc, Array arr, BiFunction<Array, Double, Integer> searcher) {
+        arr.display();
+        System.out.print("Enter the element to find: ");
+        double elem = sc.nextDouble();
+        int idx = searcher.apply(arr, elem);
+        if (idx == -1) {
+            System.out.println("The element " + elem + " was not found in the array.");
+        } else {
+            System.out.println("The element " + elem + " was found in the array at position " + (idx + 1) + ".");
+        }
+    }
+    public static void main(String[] args) {
+        Scanner sc = new Scanner(System.in);
+        System.out.println("Menu-driven program of array searching\n");
+        System.out.println("Enter the array:");
+        Array arr = null;
+        while (true) {
+            try {
+                if (arr == null) arr = new Array();
+                menu();
+                System.out.print("Enter your choice: ");
+                int choice = sc.nextInt();
+                switch (choice) {
+                case 1:
+                    arr.takeInput();
+                    arr.display();
+                    break;
+                case 2:
+                    arr.display();
+                    break;
+                case 3:
+                    performSearch(sc, arr, ArrayOperations::linearSearch);
+                    break;
+                case 4:
+                    System.out.println("Array is sorted before binary search.");
+                    arr.sort();
+                    performSearch(sc, arr, ArrayOperations::binarySearch);
+                    break;
+                case 5:
+                    System.out.println("Bye.");
+                    return;
+                default:
+                    System.out.println("Invalid choice, try again.");
+                }
+            } catch (InputMismatchException e) {
+                System.err.println("Error: Invalid input, try again");
+                sc.nextLine();
+            } catch (Exception e) {
+                System.err.println("Error: " + e.getMessage());
+            }
+        }
+    }
+}
+
diff --git a/java/code/ArraySort.java b/java/code/ArraySort.java
new file mode 100644
index 0000000..9bee74e
--- /dev/null
+++ b/java/code/ArraySort.java
@@ -0,0 +1,113 @@
+import java.util.Scanner;
+import java.util.InputMismatchException;
+import java.util.function.Consumer;
+
+class Array {
+    private double[] arr;
+    Array() throws Exception { takeInput(); }
+    void takeInput() throws Exception {
+        Scanner sc = new Scanner(System.in);
+        System.out.print("Enter the length: ");
+        int size = sc.nextInt();
+        if (size < 0)
+            throw new Exception("Invalid length, can not be negative");
+        arr = new double[size];
+        System.out.print("Enter the array elements: ");
+        for (int i = 0; i < size; i++)
+            arr[i] = sc.nextDouble();
+    }
+    void display() {
+        System.out.print("The array elements are:");
+        for (int i = 0; i < arr.length; i++)
+            System.out.print(" " + arr[i]);
+        System.out.println();
+    }
+    double get(int i) { return arr[i]; }
+    void set(int i, double val) { arr[i] = val; }
+    int size() { return arr.length; }
+}
+
+class ArrayOperations {
+    static void bubbleSort(Array arr) {
+        int n = arr.size();
+        for (int i = 0; i < n - 1; i++) {
+            for (int j = 0; j < n - i - 1; j++) {
+                double x = arr.get(j), xp = arr.get(j + 1);
+                if (x > xp) {
+                    arr.set(j, xp);
+                    arr.set(j + 1, x);
+                }
+            }
+        }
+    }
+    static void selectionSort(Array arr) {
+        int n = arr.size();
+        for (int i = 0; i < n - 1; i++) {
+            int minidx = i;
+            for (int j = i + 1; j < n; j++)
+                if (arr.get(j) < arr.get(minidx))
+                    minidx = j;
+            double tmp = arr.get(minidx);
+            arr.set(minidx, arr.get(i));
+            arr.set(i, tmp);
+        }
+    }
+}
+
+class ArraySort {
+    static void menu() {
+        System.out.println(
+            "Menu:\n" +
+            " 1. Re-enter array\n" +
+            " 2. Display array elements\n" +
+            " 3. Perform bubble sort\n" +
+            " 4. Perform selection sort\n" +
+            " 5. Exit\n");
+    }
+    static void performSort(Array arr, Consumer<Array> sorter) {
+        System.out.print("Before sorting: ");
+        arr.display();
+        sorter.accept(arr);
+        System.out.print("After sorting: ");
+        arr.display();
+    }
+    public static void main(String[] args) {
+        Scanner sc = new Scanner(System.in);
+        System.out.println("Menu-driven program of array operations\n");
+        System.out.println("Enter the array:");
+        Array arr = null;
+        while (true) {
+            try {
+                if (arr == null) arr = new Array();
+                menu();
+                System.out.print("Enter your choice: ");
+                int choice = sc.nextInt();
+                switch (choice) {
+                case 1:
+                    arr.takeInput();
+                    arr.display();
+                    break;
+                case 2:
+                    arr.display();
+                    break;
+                case 3:
+                    performSort(arr, ArrayOperations::bubbleSort);
+                    break;
+                case 4:
+                    performSort(arr, ArrayOperations::selectionSort);
+                    break;
+                case 5:
+                    System.out.println("Bye.");
+                    return;
+                default:
+                    System.err.println("Invalid choice, try again.");
+                }
+            } catch (InputMismatchException e) {
+                System.err.println("Error: Invalid input, try again");
+            } catch (Exception e) {
+                System.err.println("Error: " + e.getMessage());
+            }
+        }
+    }
+}
+
diff --git a/java/code/BankAccountExample.java b/java/code/BankAccountExample.java
new file mode 100644
index 0000000..487a564
--- /dev/null
+++ b/java/code/BankAccountExample.java
@@ -0,0 +1,155 @@
+import java.util.ArrayList;
+import java.util.Scanner;
+
+class BankAccount {
+    String name, address;
+    long accountNo;
+    double balance;
+    BankAccount(String name, String address, long accountNo, double balance) {
+        this.name = name;
+        this.address = address;
+        this.accountNo = accountNo;
+        this.balance = balance;
+    }
+    static BankAccount takeInput(Scanner sc) {
+        System.out.println("Enter details of bank account:");
+        System.out.print("  Name: ");
+        String name = sc.nextLine();
+        System.out.print("  Address: ");
+        String address = sc.nextLine();
+        System.out.print("  Account No.: ");
+        long accountNo = sc.nextLong();
+        System.out.print("  Balance: ");
+        double balance = sc.nextDouble();
+        sc.skip("\n");
+        return new BankAccount(name, address, accountNo, balance);
+    }
+    long getAccountNo() { return accountNo; }
+    double getBalance() { return balance; }
+    void deposit(double amount) throws IllegalArgumentException {
+        if (amount < 0.0)
+            throw new IllegalArgumentException(
+                    "Can not deposit negative amount of money. Use withdraw() instead.");
+        balance += amount;
+    }
+    static String formatBalance(double value) { return String.format("%.2f", value); }
+    void withdraw(double amount) throws Exception {
+        if (amount < 0.0)
+            throw new IllegalArgumentException(
+                    "Can not withdraw negative amount of money. Use deposit() instead.");
+        else if (amount > balance)
+            throw new Exception(
+                "Available balance: " + formatBalance(balance) +
+                " but tried to withdraw: " + formatBalance(amount) +
+                " with the shortfall of " + formatBalance(amount - balance));
+        balance -= amount;
+    }
+    void display() {
+        System.out.println(
+            "Customer details: \n" +
+            "  Name: " + name + "\n" +
+            "  Address: " + address + "\n" +
+            "  Account Number: " + accountNo + "\n" +
+            "  Balance: " + formatBalance(balance) + "\n");
+    }
+    static BankAccount lookup(ArrayList<BankAccount> acs, long accountNo) {
+        for (var ac : acs) {
+            if (ac.getAccountNo() == accountNo) return ac;
+        }
+        return null;
+    }
+}
+
+class BankAccountExample {
+    static void menu() {
+        System.out.println(
+            "Menu:\n" +
+            " 1. Create bank account\n" +
+            " 2. Display bank account details\n" +
+            " 3. Deposit money\n" +
+            " 4. Withdraw money\n" +
+            " 5. Exit\n");
+    }
+    static BankAccount findAccount(Scanner sc, ArrayList<BankAccount> accounts) {
+        System.out.print("Enter account number: ");
+        long accountNo = sc.nextLong();
+        sc.skip("\n");
+        var ac = BankAccount.lookup(accounts, accountNo);
+        if (ac == null) {
+            System.out.println("Could not find a bank account with the given account number.");
+            System.out.println("Try again.\n");
+            return null;
+        }
+        return ac;
+    }
+    public static void main(String[] args) {
+        Scanner sc = new Scanner(System.in);
+        System.out.println("Menu-driven program for operating bank accounts:");
+        var accounts = new ArrayList<BankAccount>();
+        while (true) {
+            menu();
+            System.out.print("Enter your choice: ");
+            int choice = sc.nextInt();
+            sc.skip("\n");
+            double amount;
+            BankAccount ac;
+            switch (choice) {
+            case 1:
+                ac = BankAccount.takeInput(sc);
+                if (BankAccount.lookup(accounts, ac.getAccountNo()) != null) {
+                    System.out.println("An account already exists with the same account number.");
+                    System.out.println("Can not create account, try again.");
+                    continue;
+                }
+                accounts.add(ac);
+                break;
+            case 2:
+                ac = findAccount(sc, accounts);
+                if (ac == null) continue;
+                ac.display();
+                break;
+            case 3:
+                ac = findAccount(sc, accounts);
+                if (ac == null) continue;
+                System.out.print("Enter the amount to deposit: ");
+                amount = sc.nextDouble();
+                try {
+                    double balanceBefore = ac.getBalance();
+                    ac.deposit(amount);
+                    double balanceAfter = ac.getBalance();
+                    System.out.println("Operation successful.");
+                    System.out.println(
+                        "Balance:\n" +
+                        "  before: " + BankAccount.formatBalance(balanceBefore) + "\n" +
+                        "  after: " + BankAccount.formatBalance(balanceAfter) + "\n");
+                } catch (Exception e) {
+                    System.out.println("Error: " + e.getMessage());
+                }
+                break;
+            case 4:
+                ac = findAccount(sc, accounts);
+                if (ac == null) continue;
+                System.out.print("Enter the amount to withdraw: ");
+                amount = sc.nextDouble();
+                try {
+                    double balanceBefore = ac.getBalance();
+                    ac.withdraw(amount);
+                    double balanceAfter = ac.getBalance();
+                    System.out.println("Operation successful.");
+                    System.out.println(
+                        "Balance:\n" +
+                        "  before: " + BankAccount.formatBalance(balanceBefore) + "\n" +
+                        "  after: " + BankAccount.formatBalance(balanceAfter) + "\n");
+                } catch (Exception e) {
+                    System.out.println("Error: " + e.getMessage());
+                }
+                break;
+            case 5:
+                System.out.println("Bye.");
+                return;
+            default:
+                System.out.println("Invalid choice, try again");
+            }
+        }
+    }
+}
diff --git a/java/code/ComplexCalculations.java b/java/code/ComplexCalculations.java
new file mode 100644
index 0000000..5ce056f
--- /dev/null
+++ b/java/code/ComplexCalculations.java
@@ -0,0 +1,43 @@
+import java.util.Scanner;
+import java.util.InputMismatchException;
+
+class Complex {
+    double real, imag;
+    Complex(double r, double i) {
+        real = r;
+        imag = i;
+    }
+    @Override
+    public String toString() {
+        return real + (imag > 0.0 ? " + " : " - ") + Math.abs(imag) + "i";
+    }
+}
+
+class ComplexOperations {
+    static Complex add(Complex a, Complex b) {
+        return new Complex(a.real + b.real, a.imag + b.imag);
+    }
+}
+
+class ComplexCalculations {
+    static Complex takeComplexInput() {
+        var sc = new Scanner(System.in);
+        System.out.print("  Enter real part: ");
+        var real = sc.nextDouble();
+        System.out.print("  Enter imaginary part: ");
+        var imaginary = sc.nextDouble();
+        return new Complex(real, imaginary);
+    }
+    public static void main(String args[]) {
+        try {
+            System.out.println("First complex number:-");
+            var x = takeComplexInput();
+            System.out.println("Second complex number:-");
+            var y = takeComplexInput();
+            System.out.println("(" + x + ") + (" + y + ") = " + ComplexOperations.add(x, y));
+        } catch (InputMismatchException e) {
+            System.err.println("Invalid number given as input");
+        }
+    }
+}
+
diff --git a/java/code/ConeCalculations.java b/java/code/ConeCalculations.java
new file mode 100644
index 0000000..1b8e64c
--- /dev/null
+++ b/java/code/ConeCalculations.java
@@ -0,0 +1,55 @@
+import java.util.Scanner;
+import java.util.InputMismatchException;
+
+class Cone {
+    double radius, height;
+    Cone(double r, double h) {
+        radius = r;
+        height = h;
+    }
+    double volume() {
+        return Math.PI * radius * radius * height / 3.0;
+    }
+    double surfaceArea() {
+        return Math.PI * radius * (radius + Math.sqrt(height * height + radius * radius));
+    }
+    void display() {
+        System.out.println("A cone with radius " + radius + " units and height " + height + " units has surface area " + surfaceArea() + " square units and volume " + volume() + " cubic units.");
+    }
+}
+
+class ConeCalculationsCLI {
+    public static void main(String args[]) {
+        if (args.length != 2) {
+            System.err.println("Usage: ConeCalculationsCLI radius height");
+            System.exit(1);
+        }
+        try {
+            var radius = Double.parseDouble(args[0]);
+            var height = Double.parseDouble(args[1]);
+            var c = new Cone(radius, height);
+            c.display();
+        } catch (NumberFormatException e) {
+            System.err.println("Invalid number given as input");
+            System.exit(1);
+        }
+    }
+}
+
+class ConeCalculationsScan {
+    public static void main(String args[]) {
+        try {
+            var sc = new Scanner(System.in);
+            System.out.print("Enter radius: ");
+            var radius = sc.nextDouble();
+            System.out.print("Enter height: ");
+            var height = sc.nextDouble();
+            var c = new Cone(radius, height);
+            c.display();
+        } catch (InputMismatchException e) {
+            System.err.println("Invalid number given as input");
+            System.exit(1);
+        }
+    }
+}
+
diff --git a/java/code/CylinderCalculations.java b/java/code/CylinderCalculations.java
new file mode 100644
index 0000000..fac5457
--- /dev/null
+++ b/java/code/CylinderCalculations.java
@@ -0,0 +1,52 @@
+import java.util.Scanner;
+import java.util.InputMismatchException;
+
+class Cylinder {
+    double radius, height;
+    Cylinder(double r, double h) {
+        radius = r;
+        height = h;
+    }
+    double volume() {
+        return Math.PI * radius * radius * height;
+    }
+    double surfaceArea() {
+        return 2 * Math.PI * radius * height * (radius + height);
+    }
+    void display() {
+        System.out.println("A cylinder with radius " + radius + " units and height " + height + " units, has volume of " + volume() + " cubic units and surface area of " + surfaceArea() + " square units.");
+    }
+}
+
+class CylinderCalculationsCLI {
+    public static void main(String args[]) {
+        if (args.length != 2) {
+            System.err.println("Usage: CylinderCalculationsCLI radius height");
+            System.exit(1);
+        }
+        try {
+            var radius = Double.parseDouble(args[0]);
+            var height = Double.parseDouble(args[1]);
+            var cy = new Cylinder(radius, height);
+            cy.display();
+        } catch (NumberFormatException e) {
+            System.err.println("Invalid numbers");
+        }
+    }
+}
+
+class CylinderCalculationsScan {
+    public static void main(String args[]) {
+        try {
+            var sc = new Scanner(System.in);
+            System.out.print("Enter radius: ");
+            var radius = sc.nextDouble();
+            System.out.print("Enter height: ");
+            var height = sc.nextDouble();
+            var cy = new Cylinder(radius, height);
+            cy.display();
+        } catch (InputMismatchException e) {
+            System.err.println("Invalid numbers");
+        }
+    }
+}
diff --git a/java/code/FindNumberInArray.java b/java/code/FindNumberInArray.java
new file mode 100644
index 0000000..2bf7f1a
--- /dev/null
+++ b/java/code/FindNumberInArray.java
@@ -0,0 +1,72 @@
+import java.util.Scanner;
+import java.util.InputMismatchException;
+
+class Number {
+    private double value;
+    Number(double n) {
+        value = n;
+    }
+    double valueOf() {
+        return value;
+    }
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof Number) {
+            return value == ((Number)o).valueOf();
+        }
+        return false;
+    } 
+}
+
+class NumberArray {
+    Number[] array;
+    NumberArray(double arr[]) {
+        array = new Number[arr.length];
+        for (int i = 0; i < arr.length; i++) {
+            array[i] = new Number(arr[i]);
+        }
+    }
+    int find(Number n) {
+        for (int i = 0; i < array.length; i++) {
+            if (array[i].equals(n)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+    void display() {
+        System.out.print("An array of numbers with " + array.length + " elements:");
+        for (int i = 0; i < array.length; i++) {
+            System.out.print(" " + array[i].valueOf());
+        }
+        System.out.println();
+    }
+}
+
+class FindNumberInArray {
+    public static void main(String args[]) {
+        try {
+            var sc = new Scanner(System.in);
+            System.out.print("Enter length: ");
+            var length = sc.nextInt();
+            var arr = new double[length];
+            System.out.print("Enter array elements: ");
+            for (int i = 0; i < length; i++) {
+                arr[i] = sc.nextDouble();
+            }
+            var narr = new NumberArray(arr);
+            System.out.print("Given: ");
+            narr.display();
+            System.out.print("Enter element to find in array: ");
+            var num = new Number(sc.nextDouble());
+            var pos = narr.find(num);
+            if (pos == -1) {
+                System.out.println("Could not find the number " + num.valueOf() + " in the array.");
+                return;
+            }
+            System.out.println("The number " + num.valueOf() + " was found in the array at position " + (pos + 1) + ".");
+        } catch (InputMismatchException e) {
+            System.err.println("Invalid number given as input");
+        }
+    }
+}
diff --git a/java/code/MatrixOperations.java b/java/code/MatrixOperations.java
new file mode 100644
index 0000000..9cc6768
--- /dev/null
+++ b/java/code/MatrixOperations.java
@@ -0,0 +1,172 @@
+import java.util.ArrayList;
+import java.util.Scanner;
+import java.util.InputMismatchException;
+import java.util.function.BinaryOperator;
+
+class Matrix {
+    private int rows, cols;
+    private float mat[][];
+    Matrix(int r, int c) {
+        rows = r;
+        cols = c;
+        mat = new float[rows][cols];
+    }
+    int rows() { return rows; }
+    int cols() { return cols; }
+    float get(int i, int j) { return mat[i][j]; }
+    void set(int i, int j, float v) { mat[i][j] = v; }
+    void input(Scanner sc) {
+        for (int i = 0; i < rows; i++) {
+            for (int j = 0; j < cols; j++) {
+                mat[i][j] = sc.nextFloat();
+            }
+        }	
+    }
+    void display() {
+        for (int i = 0; i < rows; i++) {
+            for (int j = 0; j < cols; j++) {
+                System.out.format(mat[i][j] + "\t");
+            }
+            System.out.println();
+        }
+    }
+}
+
+class MatrixOperations {
+    static Matrix add(Matrix x, Matrix y) throws IllegalArgumentException {
+        int xr = x.rows(), xc = x.cols(), yr = y.rows(), yc = y.cols();
+        if (!((xr == yr) && (xc == yc))) {
+            throw new IllegalArgumentException("Incompatible matrix arguments for addition");
+        }
+        Matrix s = new Matrix(xr, yc);
+        for (int i = 0; i < xr; i++) {
+            for (int j = 0; j < yc; j++) {
+                var v = x.get(i, j) + y.get(i, j);
+                s.set(i, j, v);
+            }
+        }
+        return s;
+    }
+    static Matrix subtract(Matrix x, Matrix y) throws IllegalArgumentException {
+        int xr = x.rows(), xc = x.cols(), yr = y.rows(), yc = y.cols();
+        if (!((xr == yr) && (xc == yc))) {
+            throw new IllegalArgumentException("Incompatible matrix arguments for subtraction");
+        }
+        Matrix d = new Matrix(xr, yc);
+        for (int i = 0; i < xr; i++) {
+            for (int j = 0; j < yc; j++) {
+                var v = x.get(i, j) - y.get(i, j);
+                d.set(i, j, v);
+            }
+        }
+        return d;
+    }
+    static Matrix multiply(Matrix x, Matrix y) throws IllegalArgumentException {
+        int xr = x.rows(), xc = x.cols(), yr = y.rows(), yc = y.cols();
+        if (xc != yr) {
+            throw new IllegalArgumentException("Incompatible matrix arguments for multiplication");
+        }
+        Matrix p = new Matrix(xr, yc);
+        for (int i = 0; i < xr; i++) {
+            for (int j = 0; j < yc; j++) {
+                float v = 0;
+                for (int k = 0; k < xc; k++) {
+                    v += x.get(i, k) * y.get(k, j);
+                }
+                p.set(i, j, v);
+            }
+        }
+        return p;
+    }
+}
+
+class MatrixOperationsCLI {
+    static void menu() {
+        System.out.println(
+            "Menu options:\n" +
+            " 1. Matrix input\n" +
+            " 2. Matrix display\n" +
+            " 3. Matrix addition\n" +
+            " 4. Matrix subtraction\n" +
+            " 5. Matrix multiplication\n" +
+            " 6. Exit");
+    }
+    static Matrix takeMatrix(Scanner sc) {
+        System.out.print("Enter number of rows and columns: ");
+        var rows = sc.nextInt();
+        var cols = sc.nextInt();
+        var m = new Matrix(rows, cols);
+        System.out.println("Enter the matrix elements: ");
+        m.input(sc);
+        return m;
+    }
+    static void displayMatrix(Scanner sc, ArrayList<Matrix> ms) {
+        var size = ms.size();
+        System.out.print("Enter which matrix to display " +
+                         "(out of " + size + " matrices): ");
+        var index = sc.nextInt() - 1;
+        if (index < 0 || index > size) {
+            System.err.println("Invalid index of matrix");
+            return;
+        }
+        System.out.println("The matrix " + (index + 1) + ":");
+        ms.get(index).display();
+    }
+    static void operate(Scanner sc, ArrayList<Matrix> ms, String opName, BinaryOperator<Matrix> op) {
+        var size = ms.size();
+        System.out.print("Enter which two matrices to " + opName +
+                         " (out of " + size + " matrices): ");
+        int xi = sc.nextInt() - 1, yi = sc.nextInt() - 1;
+        if (xi < 0 || xi > size || yi < 0 || yi > size) {
+            System.err.println("Invalid index of matrix");
+            return;
+        }
+        try {
+            var m = op.apply(ms.get(xi), ms.get(yi));
+            ms.add(m);
+            System.out.println("The resulting matrix " + (size + 1) + ":");
+            m.display();
+        } catch (IllegalArgumentException e) {
+            System.out.println("Error in the operation: " + e.getMessage());
+        }
+    }
+    public static void main(String args[]) {
+        var sc = new Scanner(System.in);
+        var ms = new ArrayList<Matrix>(); 
+        System.out.println("Menu-driven program for matrix operations");
+        while (true) {
+            try {
+                menu();
+                System.out.print("Enter your choice: ");
+                var choice = sc.nextInt();
+                switch (choice) {
+                case 1:
+                    ms.add(takeMatrix(sc));
+                    break;
+                case 2:
+                    displayMatrix(sc, ms);
+                    break;
+                case 3:
+                    operate(sc, ms, "add", MatrixOperations::add);
+                    break;
+                case 4:
+                    operate(sc, ms, "subtract", MatrixOperations::subtract);
+                    break;
+                case 5:
+                    operate(sc, ms, "multiply", MatrixOperations::multiply);
+                    break;
+                case 6:
+                    System.out.println("Bye");
+                    return;
+                default:
+                    System.err.println("Invalid choice, try again.");
+                    break;
+                }
+            } catch (InputMismatchException e) {
+                System.err.println("Invalid input, try again.");
+            } catch (Exception e) {
+                System.err.println("Error: " + e.getMessage());
+            }
+        }
+    }
+}
diff --git a/java/code/SingletonExample.java b/java/code/SingletonExample.java
new file mode 100644
index 0000000..68e5655
--- /dev/null
+++ b/java/code/SingletonExample.java
@@ -0,0 +1,23 @@
+class Singleton {
+    private static Singleton instance;
+    private Singleton() {
+        System.out.println("Creating singleton instance");
+    }
+    public static Singleton getInstance() {
+        if (instance == null) {
+            instance = new Singleton();
+        }
+        System.out.println("Providing singleton instance");
+        return instance;
+    }
+}
+
+class SingletonExample {
+    public static void main(String[] args) {
+        Singleton s1 = Singleton.getInstance();
+        Singleton s2 = Singleton.getInstance();
+        if (s1 == s2)
+            System.out.println("The singleton instances are identical.");
+    }
+}
+
diff --git a/java/code/StaticExecution.java b/java/code/StaticExecution.java
new file mode 100644
index 0000000..7aa19c8
--- /dev/null
+++ b/java/code/StaticExecution.java
@@ -0,0 +1,30 @@
+import java.util.Random;
+
+class StaticExample {
+    private static int objectCount = 0;
+    static int getObjectCount() { return objectCount; }
+    static {
+        System.out.println("Executing static block in StaticExample");
+    }
+    StaticExample() {
+        if (objectCount == 0)
+            System.out.println("Executing StaticExample constructor for the first time");
+        objectCount++;
+    }
+}
+
+class StaticExecution {
+    static {
+        System.out.println("Executing static block in StaticExecution");
+    }
+    public static void main(String args[]) {
+        System.out.println("Executing static main method in StaticExecution");
+        int c = new Random().nextInt(10) + 1;
+        for (int i = 0; i < c; i++) {
+            var ex = new StaticExample();
+        }
+        System.out.println("The number of objects of StaticExample created: " +
+            StaticExample.getObjectCount());
+    }
+}
+
diff --git a/java/code/StringOperations.java b/java/code/StringOperations.java
new file mode 100644
index 0000000..de817ce
--- /dev/null
+++ b/java/code/StringOperations.java
@@ -0,0 +1,112 @@
+import java.util.Scanner;
+
+class MyString {
+    String str;
+
+    MyString(String s) { str = s; }
+
+    String valueOf() { return str; }
+
+    int countWords() {
+        int count = 0, size = str.length();
+        enum state { WORD, SPACE };
+        state st = state.WORD;
+        for (int i = 0; i < size; i++) {
+            char c = str.charAt(i);
+            if (c == ' ' || c == '\t' || c == '\n' || c == '\r') {
+                st = state.SPACE;
+            } else if (st != state.WORD) {
+                st = state.WORD;
+                count++;
+            }
+        }
+        return count;
+    }
+
+    MyString reverse() {
+        char[] arr = str.toCharArray();
+        int end = arr.length - 1;
+        for (int i = 0; i < arr.length / 2; i++, end--) {
+            char tmp = arr[i];
+            arr[i] = arr[end];
+            arr[end] = tmp;
+        }
+        return new MyString(String.copyValueOf(arr));
+    }
+    
+    MyString toLowerCase() {
+        char[] arr = str.toCharArray();
+        char[] narr = new char[arr.length];
+        for (int i = 0; i < arr.length; i++) {
+            char c = arr[i];
+            if ('A' <= c && c <= 'Z') c += 'a' - 'A';
+            narr[i] = c;
+        }
+        return new MyString(String.copyValueOf(narr));
+    }
+    
+    boolean equals(MyString ms) {
+        char[] arr1 = str.toCharArray();
+        char[] arr2 = ms.valueOf().toCharArray();
+        if (arr1.length != arr2.length) return false;
+        for (int i = 0; i < arr1.length; i++) {
+            if (arr1[i] != arr2[i]) return false;
+        }
+        return true;
+    }
+
+    boolean isCaseInsensitivePalindrome() {
+        return str.toLowerCase().equals(reverse().toLowerCase().valueOf());
+    }
+}
+
+class StringOperations {
+    static void menu() {
+        System.out.println(
+            "Options:\n" +
+            " 1. Re-enter a string\n" +
+            " 2. Display the string\n" +
+            " 3. Count words in the string\n" +
+            " 4. Reverse the string\n" +
+            " 5. Case-insensitively check whether the string is palindrome or not\n" +
+            " 6. Exit\n");
+    }
+    public static void main(String[] args) {
+        Scanner sc = new Scanner(System.in);
+        System.out.println("Menu-driven program for string operations");
+        System.out.print("Enter a string: ");
+        MyString ms = new MyString(sc.nextLine());
+        while (true) {
+            menu();
+            System.out.print("Enter your choice: ");
+            int choice = sc.nextInt();
+            sc.skip("\n");
+            switch (choice) {
+            case 1:
+                System.out.print("Enter a string: ");
+                ms = new MyString(sc.nextLine());
+                break;
+            case 2:
+                System.out.println("The string is: " + ms.valueOf());
+                break;
+            case 3:
+                int count = ms.countWords();
+                System.out.println("The string has " + count + " words.");
+                break;
+            case 4:
+                System.out.println("The given string reversed is: " + ms.reverse().valueOf());
+                break;
+            case 5:
+                System.out.println("The given string is" +
+                        (ms.isCaseInsensitivePalindrome() ? "" : "n't") +
+                        " case-insensitively palindrome.");
+                break;
+            case 6:
+                System.out.println("Bye.");
+                return;
+            default:
+                System.out.println("Invalid choice, try again.");
+            }
+        }
+    }
+}
diff --git a/java/code/StudentsArray.java b/java/code/StudentsArray.java
new file mode 100644
index 0000000..b526a44
--- /dev/null
+++ b/java/code/StudentsArray.java
@@ -0,0 +1,91 @@
+import java.util.*;
+
+class Subject {
+    String title;
+    int theory;
+
+    Subject(String title, int theory) {
+        this.title = title;
+        this.theory = theory;
+    }
+
+    static Subject input(Scanner sc) {
+        System.out.println("Enter details of subject:");
+        System.out.print("Enter title: ");
+        String title = sc.nextLine();
+        System.out.print("Enter theory marks: ");
+        int theory = sc.nextInt();
+        sc.skip("\n");
+        return new Subject(title, theory);
+    }
+    int getTheoryMarks() { return theory; }
+
+    void display() {
+        System.out.println("  Marks obtained in " + title + ": " + theory);
+    }
+}
+
+class Student {
+    final static int SUBJECT_COUNT = 3;
+    long roll;
+    String name;
+    String stream;
+    Subject[] subjects;
+
+    Student(long roll, String name, String stream, Subject[] subjects) {
+        this.roll = roll;
+        this.name = name;
+        this.stream = stream;
+        this.subjects = subjects;
+    }
+
+    static Student input(Scanner sc) {
+        System.out.println("Enter the details of the student:");
+        System.out.print("Enter Roll no.: ");
+        long roll = sc.nextLong();
+        sc.skip("\n");
+        System.out.print("Enter name: ");
+        String name = sc.nextLine();
+        System.out.print("Enter stream: ");
+        String stream = sc.nextLine();
+        Subject[] subjects = new Subject[SUBJECT_COUNT];
+        for (int i = 0; i < subjects.length; i++) {
+            System.out.print("For subject " + (i + 1) + ": ");
+            subjects[i] = Subject.input(sc);
+        }
+        return new Student(roll, name, stream, subjects);
+    }
+
+    void display() {
+        System.out.println("Student details:");
+        System.out.println("  Roll No.: " + roll);
+        System.out.println("  Name: " + name);
+        System.out.println("  Stream: " + stream);
+        int totalMarks = 0;
+        for (Subject subject : subjects) {
+            subject.display();
+            totalMarks += subject.getTheoryMarks();
+        }
+        double average = ((double)totalMarks) / subjects.length;
+        System.out.println("  Average percentage: " + String.format("%.2f", average) + "%");
+    }
+}
+
+class StudentsArray {
+    public static void main(String[] args) {
+        var sc = new Scanner(System.in);
+        System.out.println("Enter the number of students: ");
+        Student[] students = new Student[sc.nextInt()];
+        System.out.println("Enter the details of the students:");
+        for (int i = 0; i < students.length; i++) {
+            System.out.print("For student " + (i + 1) + ": ");
+            students[i] = Student.input(sc);
+        }
+        System.out.println("Displaying the details of the students:");
+        for (int i = 0; i < students.length; i++) {
+            System.out.println("\nFor student " + (i + 1) + ": ");
+            students[i].display();
+        }
+    }
+}
+
diff --git a/java/dbld b/java/dbld
new file mode 100755
index 0000000..440b2c2
--- /dev/null
+++ b/java/dbld
@@ -0,0 +1,6 @@
+#!/bin/sh
+# Build assignment document for an assignment.
+# AssignmentName in $1 and typst(1) subcommand optionally in $2 (default c).
+
+typst ${2:-c} --root $PWD text/$1.typ docs/$1.pdf
+
diff --git a/java/index.typ b/java/index.typ
new file mode 100644
index 0000000..3cf144f
--- /dev/null
+++ b/java/index.typ
@@ -0,0 +1,93 @@
+#import "template.typ": *
+#show: body => apply(body)
+#set text(size: 1.1em)
+#set raw(lang: "java-new")
+#let semibold(body) = text(weight: 600, body)
+#text(size: 1.4em, align(center)[#semibold[Lab Assignments] \ _on_ \ #semibold[Object Oriented Programming using Java]])
+#set enum(full: true, numbering: (..args) => {
+  let patterns = ("1.", "a)")
+  let pattern = patterns.at(calc.min(args.pos().len(), patterns.len()) - 1)
+  numbering(pattern, args.pos().last())
+})
+
++ Write a menu-driven program to implement linear and binary search on an object of a custom array class.
++ Write a menu-driven program to implement bubble and selection sort on an object of a custom array class.
++ Write a menu-driven program to create a class with a `String` member variable and perform basic string operations:
+  - count the number of words,
+  - reverse the string, and
+  - case-insensitively check whether the string is palindrome or not.
++ Write a menu-driven program to perform addition, subtraction and multiplication operations on objects of a custom matrix class.
++ Write a program to add two numbers by taking input using command line input, the `Scanner` class and the `BufferedReader` class.
++ Write a program to find the surface area and volume of a cylinder using constructors - keyboard input or command-line input.
++ Write a program to add two complex numbers using concept of methods returning objects and methods taking objects as parameters.
++ Write a program to find a number from an array of number objects.
++ Write a program to show that `static` blocks get executed before any object creation and demonstrate the use of static variable to count the number of objects.
++ Write a program to implement a singleton class.
++ Write a program to make a student class with attributes for _roll number_, _name_ and _stream_. Assume that a student studies 3 subjects having full marks of 100 each. Each subject has a _title_ and _theory marks_. From the main class, create an array of such students. Show their specific information, along with average percentage of marks.
++ Design a class to represent a bank account. Include the following:
+  #pad(left: 1em)[
+  / Fields :
+    - Name of the depositor
+    - Address of the depositor
+    - Account number
+    - Balance amount in the account
+  / Methods :
+    - To assign initial values
+    - To deposit an amount
+    - To withdraw an amount after checking balance
+    - To display the name, address and balance of a customer.
+  ]
+  From `main()` create object and call these methods.
++ Write a program to create a class `Shape` with 4 methods to calculate the areas of triangle, rectangle, square, and circle using method overloading.
++ Write a program to create an abstract class `Shape` with two abstract methods, `area()` and `display()` and make three concrete derived classes `Rectangle`, `Circle` and `Triangle` which can calculate area and display them seperately.
++ Write a program to create a class `Parent` having instance variables `id`, `name` and `address`; a class `ChildOne` having instance variables `id`, `name`, `address` and `marks`; another class `ChildTwo` with instance variables `id`, `name`, `address`, `qualification` and `salary`. Design the program using `super` call with proper parameters within each class and define your own method to display values of the member variable and use an object of each class from `main()` to display their properties.
++ Write a program to create a base class named `Rectangle` and another class named `Cuboid` deriving `Rectangle` overloading the constructors and print surface area and volume of a `Cuboid` object.
++ Write a program to create a class `Employee` with instance variables `name` and `id`; a subclass of `Employee` named `Scientist` with instance variables `no_of_publication` and `experience`; and its subclass named `DScientist` with instance variable `award`; implement the `public String toString() { }` method in each class to describe about its object with the member variables and from `main()` method create an object of each class and print each object.
++ Write a program to create a class named `CircularBase` containing a method `getArea()` to calculate the base area, an interface named `_3dShape` with two methods `calArea()` and `calVolume()`, two subclasses of `CircularBase` named `Cone` and `Cylinder` implementing `_3dShape`; calculate the base area and volume of these shapes with the help of `calArea()` method.
+
+#line(length: 100%)
+
+#colbreak()
+
+=== assignment(3)
+#objective[To learn about inheritance, polymorphism, and abstract classes.]
+
++ Create a class shape with three methods to calculate area of triangle, rectangle and square with method overloading.
++ Create an abstract class `Shape` with two abstract methods, `area()` and `disp()`. Now design three concrete classes `Rectangle`, `Circle` and `Triangle` can compute area and display its separately.
++ Overload the constructors for classes `Area` and `Volume` of a rectangular figure and also display its area and volume. `Area` is the superclass and `Volume` is the subclass.
++ Create a class `Employee`, having instance variables `name` and `id`. Create its subclass named `Scientist` which has instance variables `no_of_publication` and `experience`. Now create its subclass, say `DScientist` which has instance variable `award`. Put a method like: `public String toString() { }` in every class where you describe about the class and from `main()` method create object of each class and print each object.
++ Create a class with a method `void show()` and make three subclasses of it and all subclasses have this `show()` method overridden and call those methods using their corresponding object references.
++ Do the problem 4 using dynamic method dispatching.
++ Assume that a bank maintains two kinds of account for its customers, one called savings account and other called current account. The savings account provides compound interest and withdrawal facilities but no cheque book facility. The current account provides cheque book facility but no interest. Current account holders should also maintain a minimum balance (say Rs. 1000) and if the balance falls below this level a service charge is imposed (say Rs. 100). Create a class `Account` that stores customer name, account number and type of account. From this class derive two classes `Curr_Acct` and `Savn_Acct` respectively to make them more specific to their requirements. Include the necessary methods to achieve the following tasks:
+  + Accept deposit from a customer and update the balance.
+  + Display the balance.
+  + Compute and deposit interest.
+  + Permit withdrawal and update the balance.
+  + Check for minimum balance, impose penalty, if necessary, and update balance.
+  Use constructors to initialise the class members.
++ Create a class `Parent` having instance variables `id`, `name` and `address`. Create a class `ChildOne` having instance variables `id`, `name`, `address` and `marks`. Also create another class `ChildTwo` with instance variables `id`, `name`, `address`, `qualification` and `salary`. Within each class define your own method to display values of these variables. Design the program using `super` call with proper parameter and use object of each class from `main()` to display their properties.
+
+#colbreak()
+
++ Create an interface named `Shape`. Create two subclasses of it named `Circle` and `Sphere`. Create objects of the two classes and calculate their area/surface area.
++ Create an interface named `CircularBase` (that contains base details). Create another class `_3dShape` (Contains height, volume). Inherit two classes `Cone` and `Cylinder` from the interface and the class.
++ Create a class which contains an inner class. Show that inner class can use member of outer class directly, but Outer class can use member of inner class only through its object. Check the name of class file, you created.
++ Create two interfaces, each with two methods. Inherit a new interface from the two, adding a new method. Create a class by implementing the new interface and also inheriting from a concrete class. In `main()` method, create an object of derived class and call the methods [do all without package statement].
+5. Create a class with variable(s) and method(s) (all will be default accessed) under package `pOne`. Now create a class under package `pTwo`, which is subclass of firstly created class. In the method here (_i.e._ class of `pTwo`) call variable(s) and method(s) of previous class (_i.e._ class of `pOne`). If errors come, rectify them. Now from `main()` (under working directory) access members of the second class.
++ Create an interface containing three methods, in a package `pkgOne`. Implement the interface from a class under package `pkgTwo`. From `main()`, under working directory, create object of the class and call methods of interface.
+
+
+1. Take a string from keyboard and convert into character array (new one).
+2. Take a string from keyboard and a `char` array (filled up to length 5). Now append the string to that `char` array. Show the `char` array.
+3. Write a java code to differentiate `equals()` method and `==` operator.
+4. Find length of a string taken from keyboard and also find the length of that string except the spaces at the beginning and the end of the string.
+5. Sort ten names in ascending order.
+6. Check if `"Tech"` is present in `"University of Technology"` or not. If yes return its position.
+7. Take a sentence and convert it into string arrays and sort the words using any sorting technique.
+8. Show that the `String` objects are immutable but `StringBuffer` objects are mutable.
+9. Convert a `StringBuffer` object into a `String` object. Print the final result.
+10. Check whether a given string is a palindrome or not. Ignore the cases.
+11. Convert a string into an array of strings and display them [use command-line argument].
+12. Take a shopping list of five items from the command line and store them in a vector.
+13. Write a program to concatenate the contents of two strings.
+
diff --git a/java/jbld b/java/jbld
new file mode 100755
index 0000000..6acd614
--- /dev/null
+++ b/java/jbld
@@ -0,0 +1,5 @@
+#!/bin/sh
+# Compile provided Java files, keeping class files under `build/`.
+
+javac --source-path code -d build "$@"
+
diff --git a/java/output/AddTwoNumbers.typ b/java/output/AddTwoNumbers.typ
new file mode 100644
index 0000000..0d3da48
--- /dev/null
+++ b/java/output/AddTwoNumbers.typ
@@ -0,0 +1,35 @@
+#import "/template.typ": highlight-output
+==== Taking input from command line arguments
+#highlight-output[```
+$ java AddTwoNumbersCLI 
+Usage: AddTwoNumbersCLI first-number second-number
+$ java  AddTwoNumbersCLI 5 7
+Taking input from CLI arguments:
+5.0 + 7.0 = 12.0
+```]
+==== Taking input using `java.util.Scanner`
+#highlight-output[```
+$ java AddTwoNumbersScan
+Taking input using java.util.Scanner:
+Enter first number: 12
+Enter second number: 7.3
+12.0 + 7.3 = 19.3
+$ java AddTwoNumbersScan
+Taking input using java.util.Scanner:
+Enter first number: 5.1
+Enter second number: 2c
+Invalid numbers
+```]
+==== Taking input using `java.io.BufferedReader`
+#highlight-output[```
+$ java AddTwoNumbersBuf
+Taking input using java.io.BufferedReader:
+Enter first number: 11.1
+Enter second number: 9.6
+11.1 + 9.6 = 20.7
+$ java AddTwoNumbersBuf
+Taking input using java.io.BufferedReader:
+Enter first number: 78
+Enter second number: ab
+Invalid numbers
+```]
diff --git a/java/output/ArraySearch.typ b/java/output/ArraySearch.typ
new file mode 100644
index 0000000..709b10f
--- /dev/null
+++ b/java/output/ArraySearch.typ
@@ -0,0 +1,94 @@
+#import "/template.typ": highlight-output
+#highlight-output[```
+$ java ArraySearch 
+Menu-driven program of array searching
+
+Enter the array:
+Enter the length: 5
+Enter the array elements: 5 7 9 3 4
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 2
+The array elements are: 5.0 7.0 9.0 3.0 4.0
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 3
+The array elements are: 5.0 7.0 9.0 3.0 4.0
+Enter the element to find: 7
+The element 7.0 was found in the array at position 2.
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 3
+The array elements are: 5.0 7.0 9.0 3.0 4.0
+Enter the element to find: 8
+The element 8.0 was not found in the array.
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 4
+Array is sorted before binary search.
+The array elements are: 3.0 4.0 5.0 7.0 9.0
+Enter the element to find: 4
+The element 4.0 was found in the array at position 2.
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 4
+Array is sorted before binary search.
+The array elements are: 3.0 4.0 5.0 7.0 9.0
+Enter the element to find: 8
+The element 8.0 was not found in the array.
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 1
+Enter the length: 7         
+Enter the array elements: 9 -11 7 13 5 0 4  
+The array elements are: 9.0 -11.0 7.0 13.0 5.0 0.0 4.0
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 2
+The array elements are: 9.0 -11.0 7.0 13.0 5.0 0.0 4.0
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform linear search
+ 4. Perform binary search
+ 5. Exit
+
+Enter your choice: 5
+Bye.
+```]
+
diff --git a/java/output/ArraySort.typ b/java/output/ArraySort.typ
new file mode 100644
index 0000000..e670330
--- /dev/null
+++ b/java/output/ArraySort.typ
@@ -0,0 +1,59 @@
+#import "/template.typ": highlight-output
+#highlight-output[```
+$ java ArraySort
+Menu-driven program of array operations
+
+Enter the array:
+Enter the length: 5
+Enter the array	elements: 3 -5.2 -4.2 0	6
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform bubble sort
+ 4. Perform selection sort
+ 5. Exit
+
+Enter your choice: 3
+Before sorting:	The array elements are:	3.0 -5.2 -4.2 0.0 6.0
+After sorting: The array elements are: -5.2 -4.2 0.0 3.0 6.0
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform bubble sort
+ 4. Perform selection sort
+ 5. Exit
+
+Enter your choice: 2
+The array elements are:	-5.2 -4.2 0.0 3.0 6.0
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform bubble sort
+ 4. Perform selection sort
+ 5. Exit
+
+Enter your choice: 1
+Enter the length: 6
+Enter the array	elements: 3.5 -1.3 6.9 11.3 2 -7.8
+The array elements are:	3.5 -1.3 6.9 11.3 2.0 -7.8
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform bubble sort
+ 4. Perform selection sort
+ 5. Exit
+
+Enter your choice: 4
+Before sorting:	The array elements are:	3.5 -1.3 6.9 11.3 2.0 -7.8
+After sorting: The array elements are: -7.8 -1.3 2.0 3.5 6.9 11.3
+Menu:
+ 1. Re-enter array
+ 2. Display array elements
+ 3. Perform bubble sort
+ 4. Perform selection sort
+ 5. Exit
+
+Enter your choice: 5
+Bye.
+```]
+
diff --git a/java/output/CylinderCalculations.typ b/java/output/CylinderCalculations.typ
new file mode 100644
index 0000000..be42b58
--- /dev/null
+++ b/java/output/CylinderCalculations.typ
@@ -0,0 +1,16 @@
+#import "/template.typ": highlight-output
+==== Taking input from command line arguments
+#highlight-output[```
+$ java CylinderCalculationsCLI
+Usage: CylinderCalculationsCLI radius height
+$ java CylinderCalculationsCLI 2 6
+A cylinder with radius 2.0 units and height 6.0 units, has volume of 75.39822368615503 cubic units and surface area of 603.1857894892403 square units.
+
+```]
+==== Taking input from keyboard using `java.util.Scanner`
+#highlight-output[```
+$ java CylinderCalculationsScan
+Enter radius: 5
+Enter height: 13
+A cylinder with radius 5.0 units and height 13.0 units, has volume of 1021.0176124166828 cubic units and surface area of 7351.326809400116 square units.
+```]
diff --git a/java/output/MatrixOperations.typ b/java/output/MatrixOperations.typ
new file mode 100644
index 0000000..2cabe8e
--- /dev/null
+++ b/java/output/MatrixOperations.typ
@@ -0,0 +1,132 @@
+#import "/template.typ": highlight-output
+#highlight-output[```
+$ java MatrixOperationsCLI 
+Menu-driven program for matrix operations
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 1
+Enter number of rows and columns: 2 3
+Enter the matrix elements: 
+1 2 3
+4 5 6
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 1
+Enter number of rows and columns: 2 3
+Enter the matrix elements: 
+4 -3 -2
+5 7 1
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 3
+Enter which two matrices to add (out of 2 matrices): 1 2
+The resulting matrix 3:
+5.0	-1.0	1.0	
+9.0	12.0	7.0	
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 4
+Enter which two matrices to subtract (out of 3 matrices): 2 1
+The resulting matrix 4:
+3.0	-5.0	-5.0	
+1.0	2.0	-5.0	
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 1
+Enter number of rows and columns: 3 4
+Enter the matrix elements: 
+1 0 -1 2
+3 2 0 1
+0 1 -1 2
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 2
+Enter which matrix to display (out of 5 matrices): 5
+The matrix 5:
+1.0	0.0	-1.0	2.0	
+3.0	2.0	0.0	1.0	
+0.0	1.0	-1.0	2.0	
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 5
+Enter which two matrices to multiply (out of 5 matrices): 2 5
+The resulting matrix 6:
+-5.0	-8.0	-2.0	1.0	
+26.0	15.0	-6.0	19.0	
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 5
+Enter which two matrices to multiply (out of 6 matrices): 1 2
+Error in the operation: Incompatible matrix arguments for multiplication
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 3
+Enter which two matrices to add (out of 6 matrices): 2 5
+Error in the operation: Incompatible matrix arguments for addition
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 4
+Enter which two matrices to subtract (out of 6 matrices): 3 4
+The resulting matrix 7:
+2.0	4.0	6.0	
+8.0	10.0	12.0	
+Menu options:
+ 1. Matrix input
+ 2. Matrix display
+ 3. Matrix addition
+ 4. Matrix subtraction
+ 5. Matrix multiplication
+ 6. Exit
+Enter your choice: 6
+Bye
+```]
diff --git a/java/output/SingletonExample.typ b/java/output/SingletonExample.typ
new file mode 100644
index 0000000..5f1bdd9
--- /dev/null
+++ b/java/output/SingletonExample.typ
@@ -0,0 +1,9 @@
+#import "/template.typ": highlight-output
+#highlight-output[```
+$ java SingletonExample 
+Creating singleton instance
+Providing singleton instance
+Providing singleton instance
+The singleton instances are identical.
+```]
+
diff --git a/java/output/StaticExecution.typ b/java/output/StaticExecution.typ
new file mode 100644
index 0000000..43636cf
--- /dev/null
+++ b/java/output/StaticExecution.typ
@@ -0,0 +1,10 @@
+#import "/template.typ": highlight-output
+#highlight-output[```
+$ java StaticExecution 
+Executing static block in StaticExecution
+Executing static main method in StaticExecution
+Executing static block in StaticExample
+Executing StaticExample constructor for the first time
+The number of objects of StaticExample created: 7
+```]
+
diff --git a/java/output/StringOperations.typ b/java/output/StringOperations.typ
new file mode 100644
index 0000000..eae633e
--- /dev/null
+++ b/java/output/StringOperations.typ
@@ -0,0 +1,76 @@
+#import "/template.typ": highlight-output
+#highlight-output[```
+$ java StringOperations 
+Menu-driven program for string operations
+Enter a string: A quick fox jumps over a lazy dog.
+Options:
+ 1. Re-enter a string
+ 2. Display the string
+ 3. Count words in the string
+ 4. Reverse the string
+ 5. Case-insensitively check whether the string is palindrome or not
+ 6. Exit
+
+Enter your choice: 2
+The string is: A quick brown fox jumps over a lazy dog.
+Options:
+ 1. Re-enter a string
+ 2. Display the string
+ 3. Count words in the string
+ 4. Reverse the string
+ 5. Case-insensitively check whether the string is palindrome or not
+ 6. Exit
+
+Enter your choice: 3
+The string has 8 words.
+Options:
+ 1. Re-enter a string
+ 2. Display the string
+ 3. Count words in the string
+ 4. Reverse the string
+ 5. Case-insensitively check whether the string is palindrome or not
+ 6. Exit
+
+Enter your choice: 4
+The given string reversed is: .god yzal eht revo spmuj xof nworb kciuq A
+Options:
+ 1. Re-enter a string
+ 2. Display the string
+ 3. Count words in the string
+ 4. Reverse the string
+ 5. Case-insensitively check whether the string is palindrome or not
+ 6. Exit
+
+Enter your choice: 5
+The given string isn't case-insensitively palindrome.
+Options:
+ 1. Re-enter a string
+ 2. Display the string
+ 3. Count words in the string
+ 4. Reverse the string
+ 5. Case-insensitively check whether the string is palindrome or not
+ 6. Exit
+
+Enter your choice: 1
+Enter a string: Aa bB C bB Aa
+Options:
+ 1. Re-enter a string
+ 2. Display the string
+ 3. Count words in the string
+ 4. Reverse the string
+ 5. Case-insensitively check whether the string is palindrome or not
+ 6. Exit
+
+Enter your choice: 5
+The given string is case-insensitively palindrome.
+Options:
+ 1. Re-enter a string
+ 2. Display the string
+ 3. Count words in the string
+ 4. Reverse the string
+ 5. Case-insensitively check whether the string is palindrome or not
+ 6. Exit
+
+Enter your choice: 6
+Bye.
+```]
diff --git a/java/state.sql b/java/state.sql
new file mode 100644
index 0000000..a59f11f
--- /dev/null
+++ b/java/state.sql
@@ -0,0 +1,15 @@
+-- Assignment status using SQLite
+
+CREATE TABLE `assignments` (
+    `name` text, `code` boolean, `output` boolean, `text` boolean, `shown` boolean
+);
+
+INSERT INTO `assignments` VALUES 
+    ('ArraySearch', true, true, true, true),
+    ('ArraySort', true, true, true, true),
+    ('StringOperations', true, true, true, true),
+    ('MatrixOperations', true, true, true, true);
+
+.mode markdown
+SELECT * FROM `assignments`;
+
diff --git a/java/template.typ b/java/template.typ
new file mode 100644
index 0000000..47a97a1
--- /dev/null
+++ b/java/template.typ
@@ -0,0 +1,100 @@
+#import "@preview/codelst:1.0.0": sourcefile, sourcecode
+
+/* Highlights the source code file. */
+#let highlight-code-file(filename) = sourcefile(read(filename), file: filename, lang: "java-new", 
+  numbers-style: (lno) => align(right, move(dy: 1pt, text(fill: luma(120), size: 9pt, lno))))
+
+/* Highlight output code block. */
+#let highlight-output(body) = sourcecode(numbering: none, body)
+
+/* The state variable to indicate whether the end of an assignment is reached. */
+#let eoa = state("is-at-end-of-assignment", false)
+
+/* Updates the state variable to indicate the end of an assignment. */
+#let signature() = {
+  eoa.update(true)
+}
+
+/* Draws the signature construct at the bottom right corner in the footer of the last page of an assignment. */
+#let signature-footer(loc) = {
+  if eoa.at(loc) {
+    align(bottom + right,
+      move(dy: -4em, dx: -1em,
+        block(width: 15em)[
+          #v(3em)
+          #line(length: 100%) \
+          #v(-2.5em)
+          #align(center)[Teacher’s signature]
+        ]))
+    eoa.update(false)
+  }
+}
+
+/* Draws page border around the provided content, taking an optional function to be called at the footer. */
+#let apply-page-borders(body, ..font-options, footer-special-func: none) = {
+  let page-margin = (left: 0.75in, right: 0.25in, top: 0.25in, bottom: 0.25in)
+  let margin = (left: 0.65in, right: 0.15in, top: 1.5em, bottom: 1.5em)
+  let page-border-thickness = 1.25pt
+  set page(
+    margin: (..page-margin, bottom: margin.bottom + 2em),
+    numbering: "1",
+    background: align(top + start, pad(..margin, rect(width: 100%, height: 100%, stroke: page-border-thickness + gray, radius: 5pt))),
+    footer: locate(loc => {
+      align(center, move(dy: -margin.bottom + 1em, text(..font-options, size: 9pt, counter(page).display(loc.page-numbering()))))
+      if footer-special-func != none {
+        footer-special-func(loc)
+      }
+    })
+  )
+  show: block.with(breakable: true, width: 100%, inset: page-border-thickness + 1em) 
+  body
+}
+
+#let apply(body) = {
+  let body-font-settings = (font: "Nunito Sans 10pt", size: 12pt, stretch: 75%)
+//  let body-font-settings = (font: "Hanken Grotesk", size: 12pt, stretch: 75%)
+  set text(..body-font-settings)
+
+  let code-color = rgb("#f4f4f4")
+  show raw: set text(font: "Iosevka Fixed", size: 1.1em)
+  set raw(syntaxes: "vendor/Java.sublime-syntax")
+  set raw(theme: "vendor/gr.tmTheme")
+  show raw.where(block: false): box.with(
+    fill: code-color,
+    inset: (x: 3pt, y: 0pt),
+    outset: (y: 3pt),
+    radius: 2pt,
+  )
+  show raw.where(block: true): block.with(
+    fill: code-color,
+    inset: 10pt,
+    radius: 4pt,
+    width: 100%,
+  )
+  show raw.where(block: true): it => align(left, it)
+  set list(marker: ([$square.filled.tiny$], [--]))
+  set par(leading: 0.5em)
+  apply-page-borders(body, ..body-font-settings, footer-special-func: signature-footer)
+}
+
+#let scos(name) = {
+  v(1em)
+  [=== Source Code]
+  highlight-code-file("/code/" + name + ".java")
+  [=== Output]
+  let ofname = "/output/" + name + ".typ" 
+  include ofname
+}
+
+#let assignment(number, description) = align(center, [
+= #text(weight: 600, [Assignment #number])
+== #text(weight: 500, [Program statement:]) #text(weight: 400, description)
+])
+
+#let skind(kind) = [
+  ==== #text(weight: 500, kind)
+]
+
+#let objective(body) = align(center, [*Objective*: #body])
+#let oset(kind) = block(spacing: 0.6em, [===== #h(1em) #kind])
+
diff --git a/java/text/AddTwoNumbers.typ b/java/text/AddTwoNumbers.typ
new file mode 100644
index 0000000..0ef86fa
--- /dev/null
+++ b/java/text/AddTwoNumbers.typ
@@ -0,0 +1,44 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+#set par(leading: 0.575em)
+
+#assignment(5)[
+  Write a program to add two numbers by taking input from command line arguments, the `Scanner` class and the `BufferedReader` class.
+]
+
+#scos("AddTwoNumbers")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- `java.lang.Double` class:
+  - `static double parseDouble(String)`: Try to parse the provided string as a `double` value.
+- `java.util.Scanner` class:
+  - `double nextDouble()`: Scan a `double` value from the the input stream.
+- `java.io.IOException` class represents the exception to be thrown when an error occurs while performing an I/O operation.
+- `java.io.BufferedReader` class provides for he efficient reading of characters, arrays, and lines from a character-input stream, buffering characters.
+  - Constructor `BufferedReader(Reader)`: Creates a buffering character-input stream for the provided reader stream.
+  - `String readLine()`: Returns a line of text from the input stream.
+- `java.io.InputStreamReader` class adapts a byte stream into character stream using a specific character set encoding.
+  - Constructor `InputStreamReader(InputStream)`: Creates a reader stream for characters from the provided input stream with the default character set encoding.
+- `java.util.InputMismatchException` is thrown by the methods of `Scanner` class when encountering invalid input.
+- `java.lang.NumberFormatExeption` is thrown by `parseDouble` method when the provided string does not constitute a valid `double` value.
+  
+#skind[Classes and methods implemented in the program]
+
+- The `Number` class objects represents a `double` value.
+  - Constructor `Number(double)`: Create a number object for the provided value.
+  - `double valueOf()`: Returns the underlying number.
+- The `ArithmeticOperations` class has methods implementing operations on `Number`s.
+  - `static Number add(Number, Number)`: Adds two `Number`s provided and returns the sum as a `Number`.
+- `AddTwoNumbers` class contains the operation of adding when the two numbers have been provided.
+  - `static void process(double, double)`: Performs addition by creating `Number` objects from the two provided `double` values.
+- The `AddTwoNumbersCLI` orchestrates a main program with:
+  - `public static void main(String[])`: Implements addition of two numbers by taking input from command line arguments.
+- The `AddTwoNumbersScan` orchestrates a main program with:
+  - `public static void main(String[])`: Implements addition of two numbers by taking input utilising `java.util.Scanner`.
+- The `AddTwoNumbersBuf` orchestrates a main program with:
+  - `public static void main(String[])`: Implements addition of two numbers by taking input using `java.io.BufferedReader`.
+#signature()
diff --git a/java/text/ArraySearch.typ b/java/text/ArraySearch.typ
new file mode 100644
index 0000000..19e4d7f
--- /dev/null
+++ b/java/text/ArraySearch.typ
@@ -0,0 +1,44 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+#set par(leading: 0.475em)
+
+#assignment(1)[
+  Write a menu-driven program to implement linear and binary search on an object of a custom array class.
+]
+
+#scos("ArraySearch")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- `void java.util.Arrays.sort(double[])`: A static method facilitating in-place sorting of the provided array.
+- `java.util.Scanner` Class:
+  - Constructor `Scanner(java.io.InputStream)`: Creates a scanner object for scanning values from given input stream.
+  - Methods `int nextInt()`, `double nextDouble()`: Scan an integer or `double` value from the the input stream.
+- `java.util.function.BiFunction<T, U, V>` Interface:
+  - Objects implementing this interface represent functions taking two arguments of types `T` and `U`, returning a value of type `V`.
+  - Member method `V apply(T, U)` is used to invoke the underlying function.
+- `public static java.io.PrintStream System.out, System.err`: Represents the standard output and error streams.
+- `public void java.io.PrintStream.println(String)` and `public void java.io.PrintStream.print(String)`: Print text to the print stream, with or without newline at the end, respectively.
+
+#skind[Classes and methods implemented in the program]
+
+- The `Array` class acts as an array with essential methods:
+  - Constructor `Array()`: Invokes the `takeInput()` method.
+  - `void takeInput()`: Takes the array length and elements of the array from the user.
+  - `void display()`: Displays the array elements.
+  - `double get(int)`: Returns the value at the specified position.
+  - `void set(int, double)`: Sets the value at the specified position.
+  - `void sort()` Utilizes `Arrays.sort` for in-place sorting.
+  - `int size()`: Returns the size of the array.
+- The `ArrayOperations` class includes methods for performing searching operations, which takes the array and the value to search in it and returns the position of the element if it found in the array or `-1` instead.
+  - `static int linearSearch(Array, double)`: Performs linear search on the given `Array`.
+  - `static int binarySearch(Array, double)`: Conducts binary search; the array must be sorted before calling.
+- The `ArraySearch` orchestrates the main program with:
+  - `static void menu()`: Displays the menu.
+  - `static void performSearch(Scanner, Array, BiFunction<Array, Double, Integer>)`: Takes user input, performs the specified search, and displays the result.
+  - `public static void main(String[])`: Implements a menu-driven program for array searching.
+
+#signature()
diff --git a/java/text/ArraySort.typ b/java/text/ArraySort.typ
new file mode 100644
index 0000000..bc87735
--- /dev/null
+++ b/java/text/ArraySort.typ
@@ -0,0 +1,30 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+
+#assignment(2)[
+  Write a menu-driven program to implement bubble sort and selection sort on an object of a custom array class.
+]
+
+#scos("ArraySort")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- `java.util.function.Consumer<T>` Interface:
+  - Objects implementing this interface represent functions taking an argument of type `T`, returning nothing, effectively consuming the provided value.
+  - Member method `void accept(T)` is used to invoke the underlying function.
+
+#skind[Classes and methods implemented in the program]
+
+- The `ArrayOperations` class includes methods for performing sorting operations in-place.
+  - `static void bubbleSort(Array)`: Performs bubble sort on the given `Array`.
+  - `static void selectionSort(Array)`: Performs selection sort on the given `Array`.
+- The `ArraySort` orchestrates the main program with:
+  - `static void menu()`: Displays the menu.
+  - `static void performSort(Scanner, Array, Consumer<Array>)`: Performs the specified sort, and displays the array before and after the sorting operation.
+  - `public static void main(String[])`: Implements a menu-driven program for array sorting.
+
+
+#signature()
diff --git a/java/text/ComplexCalculations.typ b/java/text/ComplexCalculations.typ
new file mode 100644
index 0000000..b8df211
--- /dev/null
+++ b/java/text/ComplexCalculations.typ
@@ -0,0 +1,31 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+#set par(leading: 0.5em)
+
+#assignment(6)[
+  Write a program to add two complex numbers using concept of methods returning objects and methods taking objects as parameters.
+]
+
+#scos("ComplexCalculations")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- The `double Math.abs(double)` method returns the absolute value of the given `double` value. 
+- `java.util.Scanner` class:
+  - `double nextDouble()`: Scan a `double` value from the the input stream.
+- `java.util.InputMismatchException` is thrown by the methods of `Scanner` class when encountering invalid input.
+
+#skind[Classes and methods implemented in the program]
+
+- The `Complex` class objects represents a a complex number.
+  - Constructor `Complex(double, double)`: Create a complex number object from the provided real and imaginary parts.
+  - `public String toString()` method returns the string representation of the complex number.
+- The `ComplexOperations` class 
+- The `CylinderCalculationsCLI` orchestrates a main program with:
+  - `public static void main(String[])`: Creates a cylinder object with its radius and height given as command-line arguments.
+- The `CylinderCalculationsScan` orchestrates a main program with:
+  - `public static void main(String[])`: Creates a cylinder object with its radius and height taken from user using `java.util.Scanner`.
+#signature()
diff --git a/java/text/CylinderCalculations.typ b/java/text/CylinderCalculations.typ
new file mode 100644
index 0000000..1ee8519
--- /dev/null
+++ b/java/text/CylinderCalculations.typ
@@ -0,0 +1,34 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+#set par(leading: 0.5em)
+
+#assignment(6)[
+  Write a program to find the surface area and volume of a cylinder using constructor by taking keyboard input or command-line input.
+]
+
+#scos("CylinderCalculations")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- `java.lang.Double` class:
+  - `static double parseDouble(String)`: Try to parse the provided string as a `double` value.
+- `java.util.Scanner` class:
+  - `double nextDouble()`: Scan a `double` value from the the input stream.
+- `java.util.InputMismatchException` is thrown by the methods of `Scanner` class when encountering invalid input.
+- `java.lang.NumberFormatExeption` is thrown by `parseDouble` method when the provided string does not constitute a valid `double` value.
+  
+#skind[Classes and methods implemented in the program]
+
+- The `Cylinder` class objects represents a cylinder, a 3D geometric shape.
+  - Constructor `Cylinder(double, double)`: Create a cylinder object of the provided radius and height.
+  - `double volume()`: Returns the volume of the cylinder.
+  - `double surfaceArea()`: Returns the surface area of the cylinder.
+  - `void display()`: Display information about the cylinder.
+- The `CylinderCalculationsCLI` orchestrates a main program with:
+  - `public static void main(String[])`: Creates a cylinder object with its radius and height given as command-line arguments.
+- The `CylinderCalculationsScan` orchestrates a main program with:
+  - `public static void main(String[])`: Creates a cylinder object with its radius and height taken from user using `java.util.Scanner`.
+#signature()
diff --git a/java/text/MatrixOperations.typ b/java/text/MatrixOperations.typ
new file mode 100644
index 0000000..bcb6ce8
--- /dev/null
+++ b/java/text/MatrixOperations.typ
@@ -0,0 +1,47 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+#set par(leading: 0.6em)
+
+#assignment(4)[
+  Write a menu-driven program to perform addition, subtraction and multiplication operations on matrix objects.
+]
+
+#scos("MatrixOperations")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- `java.util.Scanner` class:
+  - `float nextFloat()`: Scan a `float` value from the the input stream.
+- `java.util.function.BinaryOperator<T>` Interface:
+  - Objects of this interface represent operations upon two operands of the same type, producing a result of the same type as the operands.
+  - This is a subinterface of `BiFunction<T, T, T>` whose functional method is `T apply(T, T)`.
+- `java.lang.IllegalArgumentException` class represents the exception to be thrown when an illegal argument is provided to a function.
+- `java.util.ArrayList<T>` class provides a resizeable array from the Java Collections framework.
+  - `T get(int)`: Returns the value at the specified position in the list.
+  - `void add(T)`: Appends the specified element to the end of the list.
+- `java.util.InputMismatchException` is thrown by the methods of `Scanner` class when encountering invalid input.
+  
+#skind[Classes and methods implemented in the program]
+
+- The `Matrix` class provides sufficient interface to operate on a matrix of `float` values.
+  - Constructor `Matrix(int, int)`: Creates the underlying two dimensional array with the given matrix dimensions.
+  - `int rows(), int cols()`: Returns the number of rows and columns of the matrix, respectively.
+  - `float get(int, int)`: Returns the value at the specified position.
+  - `void set(int, int, float)`: Sets the value at the specified position.
+  - `void input(Scanner)`: Take the elements of the matrix from the user using the provided `Scanner` instance.
+  - `void display()`: Displays the matrix elements in a tabular format.
+- The `MatrixOperations` class implements the matrix operations as static methods.
+  - `static Matrix add(Matrix, Matrix) throws IllegalArgumentException`,
+  - `static Matrix subtract(Matrix, Matrix) throws IllegalArgumentException`,
+  - `static Matrix multiply(Matrix, Matrix) throws IllegalArgumentException`:
+    Perform the respective operations on the provided two matrices, taking care of the compatibility to the operations.
+- The `MatrixOperationsCLI` orchestrates the main program with:
+  - `static void menu()`: Displays the menu.
+  - `static Matrix takeMatrix(Scanner)`: Takes requisite user input to create a new matrix object.
+  - `static void displayMatrix(Scanner, ArrayList<Matrix>)`: Asks the user to choose the matrix to display among the available matrices and displays it.
+  - `static void operate(Scanner, ArrayList<Matrix>, String, BinaryOperator<Matrix>)`: Performs the specified operation on the matrices chosen by the user.
+  - `public static void main(String[])`: Implements a menu-driven program for the matrix operations.
+#signature()
diff --git a/java/text/StaticExecution.typ b/java/text/StaticExecution.typ
new file mode 100644
index 0000000..00b4ed0
--- /dev/null
+++ b/java/text/StaticExecution.typ
@@ -0,0 +1,29 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+#set par(leading: 0.75em)
+
+#assignment(10)[
+  Write a program to show that `static` blocks get executed before any object creation and implement the use of static variable to count the number of objects.
+]
+
+#scos("StaticExecution")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- `java.util.Random` class:
+  Provides methods for generating pseudorandom numbers.
+  - `int nextInt(int)`: Returns a pseudorandom, uniformly-distributed, random number between 0 (inclusive) and provided value (exclusive).
+
+#skind[Classes and methods implemented in the program]
+
+- `StaticExample` class:
+  The class being used to demonstrate the order of execution of static block.
+  - `static int getObjectCount()`: Returns the object count of this class.
+  - Constructor `StaticExample()`: Shows a message first time it is called, i.e. when the first object is created. Increments the object count static variable.
+- `StaticExecution` class contains the main method of the program.
+  - `public static void main(String[])`: Creates a random number of objects of the `StaticExample` class and shows the number of objects created.
+
+#signature()
diff --git a/java/text/StringOperations.typ b/java/text/StringOperations.typ
new file mode 100644
index 0000000..210e4a9
--- /dev/null
+++ b/java/text/StringOperations.typ
@@ -0,0 +1,45 @@
+#import "/template.typ": *
+#show: A => apply(A)
+#set raw(lang: "java-new")
+#set par(leading: 0.55em)
+
+#assignment(3)[
+  Write a menu-driven program to create a class with a String member variable and perform basic string operations:
+  #box(align(left, [
+  - count the number of words,
+  - case-insensitively check whether the string is palindrome, and
+  - reverse the string.]))
+]
+
+#scos("StringOperations")
+
+=== Discussion
+
+#skind[Classes, interfaces and methods used from Java standard library]
+
+- `java.util.Scanner` Class:
+  - Method `String nextLine()`: Scan a line of text as a string from the the input stream.
+- `java.lang.String` Class:
+  - `int length()` method: Returns the length of the string.
+  - `char charAt(int)`: Returns the character in the string at the provided position.
+  - `char[] toCharArray()`: Returns an array of characters corresponding to the string.
+  - `static String copyValueOf(char[])`: Creates a new string from the provided character array.
+  
+#skind[Classes and methods implemented in the program]
+
+- `MyString` Class:
+  Provides the methods implementing the specified operations.
+  - `String str` is the underlying string object upon which the operations are to be performed.
+  - Constructor `MyString(String)`: Create an object of this class for the provided string.
+  - `String valueOf()`: Returns the underlying string object.
+  - `int countWords()`: Counts the words in the underlying string manually by  iterating over the characters in the string.
+  - `MyString reverse()`: Returns a new object of MyString with the underlying string reversed manually by iterating over characters.
+  - `MyString toLowerCase()`: Returns a new object of MyString with its characters manually converted to lower-case.
+  - `boolean equals(MyString)`: Check whether the underlying strings are equal by comparing the arrays of characters.
+  - `boolean isCaseInsensitivePalindrome()`: Checks whether the underlying string is a palindrome case-insensitively using the `reverse()`, `toLowerCase()` and `equals()` method.
+- The `StringOperations` orchestrates the main program with:
+  - `static void menu()`: Displays the menu.
+  - `public static void main(String[])`: Implements a menu-driven program for the specified string operations.
+
+
+#signature()
diff --git a/java/vendor/Java.sublime-syntax b/java/vendor/Java.sublime-syntax
new file mode 100644
index 0000000..c13c939
--- /dev/null
+++ b/java/vendor/Java.sublime-syntax
@@ -0,0 +1,1246 @@
+%YAML 1.2
+---
+# http://www.sublimetext.com/docs/3/syntax.html
+name: java-new
+file_extensions:
+  - java
+  - bsh
+scope: source.java
+
+variables:
+  primitives: (?:boolean|byte|char|short|int|float|long|double|var)
+  storage_modifiers: (?:public|private|protected|static|final|native|synchronized|strictfp|abstract|transient|default|volatile)
+
+  id: (?:[\p{L}_$][\p{L}\p{N}_$]*)
+  classcase_id: (?:\p{Lu}[\p{L}\p{N}_$]*)
+  lowercase_id: (?:[_$]*\p{Ll}[\p{Ll}\p{N}_$]*\b)
+  uppercase_id: (?:[_$]*\p{Lu}[\p{Lu}\p{N}_$]*\b)
+
+  # One dot is mandatory to not compete with other regexes that match an id.
+  before_fqn: (?={{lowercase_id}}\s*\.)
+
+  # utility lookaround
+  lambda_lookahead: (?:\(.*\)|{{id}})\s*->
+
+  # digits
+  ddigits0: '\d[\d_]*?(_*)'
+  ddigits: (?:(_*){{ddigits0}})
+  hdigits: (?:(_*)\h[\h_]*?(_*))
+  exponent: '[-+]?{{ddigits}}'
+  eexponent: (?:[eE]{{exponent}})
+  pexponent: (?:[pP]{{exponent}})
+
+contexts:
+  prototype:
+    - match: (?=%>)
+      pop: true
+    - include: comments
+    - include: illegal-keywords
+
+  any_POP:
+    - match: (?=\S)
+      pop: true
+
+  immediate_POP:
+    - match: ''
+      pop: true
+
+  main:
+    - include: prototype
+    - include: package-statement
+    - include: import-statement
+    - include: module
+    - include: class
+    - include: annotations
+    # Get modifiers defined on a different line than the class
+    - include: storage-modifiers
+    - include: stray-braces
+    - include: code
+
+  punctuation-accessor-dot:
+    - match: \.
+      scope: punctuation.accessor.dot.java
+
+  punctuation-separator-comma:
+    - match: \,
+      scope: punctuation.separator.comma.java
+
+  punctuation-terminator-semicolon:
+    - match: ;
+      scope: punctuation.terminator.java
+
+  dot-separated-identifier:
+    - match: '{{id}}'
+    - include: punctuation-accessor-dot
+    - include: immediate_POP
+
+  package-statement:
+    - match: \bpackage\b
+      scope: keyword.other.package.java
+      push:
+        - - meta_scope: meta.package-declaration.java
+          - include: immediate_POP
+        - - match: '{{id}}'
+            set:
+              - meta_scope: meta.path.java entity.name.namespace.java
+              - include: dot-separated-identifier
+          - include: any_POP
+
+  import-statement:
+    - match: \bimport\b
+      scope: keyword.control.import.java
+      push:
+        - - meta_scope: meta.import.java
+          - include: immediate_POP
+        - import-statement-body
+
+  import-statement-body:
+    - match: \bstatic\b
+      scope: keyword.control.import.static.java
+      set: static-import-statement-body
+    - include: before-next-import
+    - match: '{{lowercase_id}}'
+      scope: meta.path.java support.type.package.java
+      set:
+        - meta_content_scope: meta.path.java
+        - include: before-next-import
+        - include: package
+        - match: \*
+          scope: meta.path.java keyword.operator.wildcard.asterisk.java
+          pop: true
+        - match: '{{classcase_id}}'
+          scope: support.class.import.java
+          set:
+            - include: before-next-import
+            - include: punctuation-accessor-dot
+            - include: import-class
+            - include: import-wildcard
+            - include: any_POP
+        - include: any_POP
+    - include: any_POP
+
+  static-import-statement-body:
+    - include: before-next-import
+    - match: '{{lowercase_id}}'
+      scope: meta.path.java support.type.package.java
+      set:
+        - meta_content_scope: meta.path.java
+        - include: before-next-import
+        - include: package
+        - match: '{{classcase_id}}'
+          scope: support.class.import.java
+          set:
+            - include: before-next-import
+            - include: punctuation-accessor-dot
+            - include: import-constant
+            - include: import-class
+            - include: import-function
+            - include: import-wildcard
+            - include: any_POP
+        - include: any_POP
+    - include: any_POP
+
+  before-next-import:
+    # Prevent next import statement to be consumed when a current statement isn't terminated with ';'.
+    - match: (?=\bimport\b)
+      pop: true
+    # For a case of a statement immediately before a class definition.
+    - match: (?=\b(?:{{storage_modifiers}}|class|interface|enum)\b)
+      pop: true
+
+  package:
+    - match: '{{lowercase_id}}'
+      scope: support.type.package.java
+    - include: punctuation-accessor-dot
+
+  all-types:
+    - include: primitive-types
+    - include: object-types
+
+  import-constant:
+    - match: '{{uppercase_id}}'
+      scope: constant.other.import.java
+
+  import-class:
+    - match: '{{classcase_id}}'
+      scope: support.class.import.java
+
+  import-function:
+    - match: '{{id}}'
+      scope: support.function.import.java
+
+  import-wildcard:
+    - match: \*
+      scope: keyword.operator.wildcard.asterisk.java
+
+  annotations:
+    - match: \@
+      scope: punctuation.definition.annotation.java
+      push:
+        - - meta_scope: meta.annotation.java
+          - include: immediate_POP
+        - annotation-parameters
+        - - meta_content_scope: meta.annotation.identifier.java
+          - include: immediate_POP
+        - annotation-type-reference
+
+  annotation-type-reference:
+    - match: '{{before_fqn}}'
+      set:
+        - meta_scope: meta.path.java
+        - match: '{{lowercase_id}}'
+          scope: variable.annotation.package.java
+        - include: punctuation-accessor-dot
+        - include: annotation-type-no-fqn
+    - include: annotation-type-no-fqn
+
+  annotation-type-no-fqn:
+    - match: '{{classcase_id}}'
+      scope: variable.annotation.java
+      set: after-annotation-type-reference
+    - include: any_POP
+
+  after-annotation-type-reference:
+    - match: \.
+      scope: punctuation.accessor.dot.java
+      set: annotation-type-no-fqn
+    - include: any_POP
+
+  annotation-parameters:
+    - match: \(
+      scope: punctuation.section.parens.begin.java
+      set:
+        - meta_scope: meta.annotation.parameters.java
+        - match: \)
+          scope: punctuation.section.parens.end.java
+          pop: true
+        - match: ({{id}})\s*(=)
+          captures:
+            1: variable.parameter.java
+            2: keyword.operator.assignment.java
+          push:
+            - match: (?=[,})])
+              pop: true
+            - include: annotations
+            - include: code
+        - include: annotation-array-initialization
+        - include: annotations
+        - include: code
+    - include: any_POP
+
+  annotation-array-initialization:
+    - match: \{
+      scope: punctuation.section.braces.begin.java
+      push:
+        - meta_scope: meta.braces.annotation-array-initialization.java
+        - include: array-initialization-common
+        - include: annotations
+
+  anonymous-classes-and-new:
+    - match: \bnew\b
+      scope: keyword.other.storage.new.java
+      push:
+        - - meta_scope: meta.instantiation.java
+          - include: immediate_POP
+        - instantiation
+
+  instantiation:
+    - match: \b{{primitives}}\b
+      scope: storage.type.primitive.java
+      set: array-definition
+    - match: '{{before_fqn}}'
+      set: [after-object-type-in-instantiation, object-type-fqn]
+    - include: object-type-instantiation-no-fqn
+
+  object-type-instantiation-no-fqn:
+    - match: '{{classcase_id}}'
+      scope: support.class.java
+      set: after-object-type-in-instantiation
+    - include: any_POP
+
+  after-object-type-in-instantiation:
+    - match: (?=\[)
+      set: array-definition
+    - match: (?=\()
+      set: object-construction
+    - match: <>
+      scope: punctuation.definition.generic.diamond.java
+      set: object-construction
+    - match: (?=<)
+      set: [after-generic-in-instantiation, generic-type-invocation]
+    - match: \.
+      scope: punctuation.accessor.dot.java
+      set: object-type-instantiation-no-fqn
+    - include: any_POP
+
+  after-generic-in-instantiation:
+    - match: (?=\[)
+      set: array-definition
+    - include: object-construction
+
+  object-construction:
+    - match: \(
+      scope: punctuation.section.parens.begin.java
+      set:
+        - meta_scope: meta.parens.constructor-arguments.java
+        - match: \)
+          scope: punctuation.section.parens.end.java
+          set:
+            - match: \{
+              scope: punctuation.section.braces.begin.java
+              set:
+                - meta_scope: meta.class.body.anonymous.java
+                - match: \}
+                  scope: punctuation.section.braces.end.java
+                  pop: true
+                - include: class-body
+            - include: any_POP
+        - include: illegal-parens-terminators
+        - include: code
+    - include: any_POP
+
+  array-definition:
+    - match: \[
+      scope: punctuation.section.brackets.begin.java
+      set:
+        - meta_scope: meta.brackets.array-initialization.java
+        - match: \]
+          scope: punctuation.section.brackets.end.java
+          set:
+            - match: (?=\[)
+              set: array-definition
+            - match: \{
+              scope: punctuation.section.braces.begin.java
+              set: array-initialization
+            - include: any_POP
+        - include: code
+    - include: any_POP
+
+  array-initialization:
+    - meta_scope: meta.braces.array-initialization.java
+    - include: array-initialization-common
+
+  array-initialization-common:
+    - match: \}
+      scope: punctuation.section.braces.end.java
+      pop: true
+    - match: \{
+      scope: punctuation.section.braces.begin.java
+      push: array-initialization
+    - include: code
+
+  class:
+    - match: (?=({{storage_modifiers}}\s+)*(?:class|(?:@)?interface|enum)\b)
+      push: [class-meta, class-type]
+
+  class-meta:
+    - meta_scope: meta.class.java
+    - include: immediate_POP
+
+  class-type:
+    - include: storage-modifiers
+    - match: (?:class|(\@?)interface)\b
+      scope: storage.type.java
+      captures:
+        1: punctuation.definition.type.java
+      set:
+        - class-block
+        - class-extends
+        - generic-type-declaration
+        - class-name
+    - match: enum\b
+      scope: storage.type.java
+      set:
+        - enum-block
+        - class-extends
+        - generic-type-declaration
+        - class-name
+    - include: any_POP
+
+  class-name:
+    - meta_scope: meta.class.identifier.java
+    - match: (?!extends|implements){{id}}\b
+      scope: entity.name.class.java
+      pop: true
+    - include: any_POP
+
+  class-extends:
+    - match: extends\b
+      scope: keyword.declaration.extends.java
+      push:
+        - - meta_scope: meta.class.extends.java
+          - match: \,
+            scope: punctuation.separator.comma.java
+            push: inherited-object-type-reference
+          - include: any_POP
+        - inherited-object-type-reference
+    - match: implements\b
+      scope: keyword.declaration.implements.java
+      push:
+        - - meta_scope: meta.class.implements.java
+          - match: \,
+            scope: punctuation.separator.comma.java
+            push: inherited-object-type-reference
+          - include: any_POP
+        - inherited-object-type-reference
+    - include: any_POP
+
+  class-block:
+    - match: \{
+      scope: punctuation.section.block.begin.java
+      set:
+        - meta_scope: meta.class.body.java meta.block.java
+        - match: \}
+          scope: punctuation.section.block.end.java
+          pop: true
+        - include: class-body
+    - include: any_POP
+
+  class-body:
+    - include: class
+    - include: annotations
+    - include: fields-and-methods
+    - include: constants-and-special-vars
+    - include: storage-modifiers
+    - include: all-types
+    - include: static-code-block
+    - include: punctuation-separator-comma
+    - include: punctuation-terminator-semicolon
+    - match: (?=<)
+      push: generic-type-declaration
+
+  enum-block:
+    - match: \{
+      scope: punctuation.section.block.begin.java
+      set:
+        - meta_scope: meta.class.body.java meta.block.java
+        - match: \}
+          scope: punctuation.section.block.end.java
+          pop: true
+        - include: enum-body
+    - include: any_POP
+
+  enum-body:
+    - match: ^(?=\s*([[:upper:]_][[:upper:][:digit:]_]*|(?!{{primitives}}|{{storage_modifiers}})[[:lower:]_][[:alnum:]_]*)\s*[,;{(])
+      push:
+        - match: (?=[;}])
+          pop: true
+        - match: \w+
+          scope: constant.other.enum.java
+          push:
+            - meta_scope: meta.enum.java
+            - match: \{
+              scope: punctuation.section.block.begin.java
+              push:
+                - meta_scope: meta.enum.body.java meta.block.java
+                - match: \}
+                  scope: punctuation.section.block.end.java
+                  pop: true
+                - include: enum-body
+            - include: parens
+            - include: any_POP
+        - include: punctuation-separator-comma
+    - include: class-body
+
+  code:
+    - include: constants-and-special-vars
+    - include: assignment
+    - include: lambdas
+    - include: strings
+    - include: anonymous-classes-and-new
+    - include: keywords-control
+    - include: method-invocations
+    - include: uppercase-identifiers
+    - include: all-types
+    - include: keywords
+    - include: code-block-include
+    - include: parens
+  code-block-include:
+    - match: \{
+      scope: punctuation.section.block.begin.java
+      push:
+        - meta_scope: meta.block.java
+        - match: \}
+          scope: punctuation.section.block.end.java
+          pop: true
+        - include: code-block
+  code-block:
+    - include: storage-modifiers
+    - include: var-type
+    - include: code
+    - include: annotations
+    - include: code-block-include
+    - include: stray-parens
+  comments:
+    - match: /\*\*/
+      scope: comment.block.empty.java punctuation.definition.comment.java
+    - include: scope:text.html.javadoc
+    - include: comments-inline
+  comments-inline:
+    - match: /\*
+      scope: punctuation.definition.comment.java
+      push:
+        - meta_scope: comment.block.java
+        - match: \*/
+          scope: punctuation.definition.comment.java
+          pop: true
+    - match: //
+      scope: punctuation.definition.comment.java
+      push:
+        - meta_scope: comment.line.double-slash.java
+        - match: \n
+          pop: true
+        - match: (?=%>)
+          pop: true
+
+  constants-and-special-vars:
+    - match: \b(true|false|null)\b
+      scope: constant.language.java
+    - match: \b(this|super)\b
+      scope: variable.language.java
+    # hexadecimal floats
+    - match: |-
+        \b(0[xX])(?x:
+          # 0x1., 0x1.1, 0x1.1p1, 0x1.1p-1, 0x1.p1, 0x1.p-1 | 0x1p1
+          {{hdigits}} (?: (\.) (?: {{hdigits}}? {{pexponent}}? \b )? | {{pexponent}} \b )
+          # 0x.1, 0x.1p1, 0x.1p-1
+          | (\.) {{hdigits}} {{pexponent}}? \b
+        )
+      scope: constant.numeric.float.hexadecimal.java
+      captures:
+        1: punctuation.definition.numeric.hexadecimal.java
+        2: invalid.illegal.numeric.java
+        3: invalid.illegal.numeric.java
+        4: punctuation.separator.decimal.java
+        5: invalid.illegal.numeric.java
+        6: invalid.illegal.numeric.java
+        7: invalid.illegal.numeric.java
+        8: invalid.illegal.numeric.java
+        9: invalid.illegal.numeric.java
+        10: invalid.illegal.numeric.java
+        11: punctuation.separator.decimal.java
+        12: invalid.illegal.numeric.java
+        13: invalid.illegal.numeric.java
+        14: invalid.illegal.numeric.java
+        15: invalid.illegal.numeric.java
+    # decimal floats
+    - match: |-
+        (?x:
+          \b{{ddigits0}}
+          (?:
+            # 1., 1.1, 1.1e1, 1.1e-1, 1.e1, 1.e-1, 1.d, 1.1d, 1.1e1d, 1.1e-1d, 1.e1d, 1.e-1d
+            (\.) (?: {{ddigits}}? {{eexponent}}? ([dDfF])? \b )?
+            # 1e1 1e1d
+            | {{eexponent}} ([dDfF])? \b
+            # 1d
+            | ([dDfF]) \b
+          )
+          # .1, .1e1, .1e-1
+          | (\.) {{ddigits}} {{eexponent}}? ([dDfF])? \b
+        )
+      scope: constant.numeric.float.decimal.java
+      captures:
+        1: invalid.illegal.numeric.java
+        2: punctuation.separator.decimal.java
+        3: invalid.illegal.numeric.java
+        4: invalid.illegal.numeric.java
+        5: invalid.illegal.numeric.java
+        6: invalid.illegal.numeric.java
+        7: storage.type.numeric.java
+        8: invalid.illegal.numeric.java
+        9: invalid.illegal.numeric.java
+        10: storage.type.numeric.java
+        11: storage.type.numeric.java
+        12: punctuation.separator.decimal.java
+        13: invalid.illegal.numeric.java
+        14: invalid.illegal.numeric.java
+        15: invalid.illegal.numeric.java
+        16: invalid.illegal.numeric.java
+        17: storage.type.numeric.java
+    # binary integers
+    - match: \b(0[bB])(_*)[01][01_]*?(_*)([lL])?\b
+      scope: constant.numeric.integer.binary.java
+      captures:
+        1: punctuation.definition.numeric.binary.java
+        2: invalid.illegal.numeric.java
+        3: invalid.illegal.numeric.java
+        4: storage.type.numeric.java
+    # hexadecimal integers
+    - match: \b(0[xX]){{hdigits}}([lL])?\b
+      scope: constant.numeric.integer.hexadecimal.java
+      captures:
+        1: punctuation.definition.numeric.hexadecimal.java
+        2: invalid.illegal.numeric.java
+        3: invalid.illegal.numeric.java
+        4: storage.type.numeric.java
+    # octal integers
+    - match: \b(0)(?:(_+)|[0-7_]+?(_*)|([\d_]+))([lL])?\b
+      scope: constant.numeric.integer.octal.java
+      captures:
+        1: punctuation.definition.numeric.octal.java
+        2: invalid.illegal.numeric.java
+        3: invalid.illegal.numeric.java
+        4: invalid.illegal.numeric.java
+        5: storage.type.numeric.java
+    # decimal integers
+    - match: \b{{ddigits0}}([lL])?\b
+      scope: constant.numeric.integer.decimal.java
+      captures:
+        1: invalid.illegal.numeric.java
+        2: storage.type.numeric.java
+
+  keywords:
+    - match: '::'
+      scope: punctuation.accessor.double-colon.java
+      push:
+        - match: '{{id}}'
+          scope: variable.function.reference.java
+          pop: true
+        - include: any_POP
+    - match: '\?|:'
+      scope: keyword.operator.ternary.java
+    - match: \binstanceof\b
+      scope: keyword.operator.word.instanceof.java
+    - match: (<<|>>>?)
+      scope: keyword.operator.bitshift.java
+    - match: (==|!=|<=|>=|<>|<|>)
+      scope: keyword.operator.comparison.java
+    - match: (\-\-|\+\+)
+      scope: keyword.operator.increment-decrement.java
+    - match: (\-|\+|\*|\/|%)
+      scope: keyword.operator.arithmetic.java
+    - match: (!|&&|\|\|)
+      scope: keyword.operator.logical.java
+    - match: (~|\^|&|\|)
+      scope: keyword.operator.bitwise.java
+    - match: (\.)(class\b)?
+      captures:
+        1: punctuation.accessor.dot.java
+        2: variable.language.java
+    - include: punctuation-separator-comma
+    - include: punctuation-terminator-semicolon
+
+  keywords-control:
+    # exceptions
+    - match: \bcatch\b
+      scope: keyword.control.exception.catch.java
+      push:
+        - meta_scope: meta.catch.java
+        - match: (?=\()
+          set:
+            - match: \(
+              scope: punctuation.section.parens.begin.java
+              set:
+                - meta_scope: meta.catch.parameters.java meta.parens.java
+                - match: \)
+                  scope: punctuation.section.parens.end.java
+                  pop: true
+                - match: \|
+                  scope: punctuation.separator.bar.java
+                - include: parameters
+        - include: any_POP
+    - match: \bfinally\b
+      scope: keyword.control.exception.finally.java
+    - match: \btry\b
+      scope: keyword.control.exception.try.java
+      push: declaration-statement-parens
+    # flow
+    - match: \bassert\b
+      scope: keyword.control.flow.assert.java
+      push:
+        - meta_scope: meta.assertion.java
+        - match: (?=;)
+          pop: true
+        - match: ':'
+          scope: punctuation.separator.expressions.java
+        - include: code
+    - match: \bbreak\b
+      scope: keyword.control.flow.break.java
+    - match: \bcontinue\b
+      scope: keyword.control.flow.continue.java
+    - match: \breturn\b
+      scope: keyword.control.flow.return.java
+    - match: \bthrow\b
+      scope: keyword.control.flow.throw.java
+    # conditional
+    - match: \bif\b
+      scope: keyword.control.conditional.if.java
+    - match: \belse\b
+      scope: keyword.control.conditional.else.java
+    - match: \bswitch\b
+      scope: keyword.control.conditional.switch.java
+    - match: \bcase\b
+      scope: keyword.control.conditional.case.java
+    - match: \bdefault\b
+      scope: keyword.control.conditional.default.java
+    # loop
+    - match: \bdo\b
+      scope: keyword.control.loop.do-while.java
+    - match: \bfor\b
+      scope: keyword.control.loop.for.java
+      push: declaration-statement-parens
+    - match: \bwhile\b
+      scope: keyword.control.loop.while.java
+
+  illegal-keywords:
+    - match: \b(goto|const)\b
+      scope: invalid.illegal.keyword.java
+
+  illegal-open-block:
+    - match: \s?(?={)
+      scope: invalid.illegal.stray-terminator-end
+      pop: true
+
+  illegal-semicolon:
+    - match: ;
+      scope: invalid.illegal.stray-terminator-end
+      pop: true
+
+  illegal-parens-terminators:
+    # Pops the stack if anything matches
+    - include: illegal-semicolon
+    - include: illegal-open-block
+
+  method-invocations:
+    - match: (\.)\s*(?=<)
+      captures:
+        1: punctuation.accessor.dot.java
+      push: generic-type-invocation
+    - match: ({{id}})\s*(\()
+      captures:
+        1: variable.function.java
+        2: punctuation.section.parens.begin.java
+      push:
+        - meta_scope: meta.function-call.java
+        - match: \)
+          scope: punctuation.section.parens.end.java
+          pop: true
+        - include: illegal-parens-terminators
+        - include: code
+
+  fields-and-methods:
+    - match: \bvoid\b
+      scope: storage.type.void.java
+      push: method
+    - match: (?={{id}}\s*\()
+      push: method
+    - match: '{{before_fqn}}'
+      push: [field-or-method, after-object-and-array-types, object-type-fqn]
+    - match: \b{{classcase_id}}
+      scope: support.class.java
+      push: [field-or-method, after-object-and-array-types]
+    - match: \b{{primitives}}\b
+      scope: storage.type.primitive.java
+      push: [field-or-method, array-brackets]
+
+  field-or-method:
+    - match: (?={{id}}\s*\()
+      set: method
+    - match: (?=\S)
+      set:
+      - include: before-next-field
+      - match: (?:({{uppercase_id}})|({{id}}))
+        captures:
+          1: entity.name.constant.java
+          2: meta.field.java
+        push: [static-assignment, array-brackets]
+      - include: punctuation-separator-comma
+      - include: any_POP
+
+  before-next-field:
+    # Prevent style from being removed from whole file when making a new expression
+    - match: (?=\b(?:{{storage_modifiers}}|{{primitives}}|void)\b)
+      pop: true
+
+  method:
+    - meta_scope: meta.method.java
+    - match: ({{classcase_id}})\s*(?=\()
+      captures:
+        1: meta.method.identifier.java entity.name.function.constructor.java
+    - match: ({{id}})\s*(?=\()
+      captures:
+        1: meta.method.identifier.java entity.name.function.java
+    - match: \(
+      scope: punctuation.section.parens.begin.java
+      push:
+        - meta_scope: meta.method.parameters.java meta.parens.java
+        - match: \)
+          scope: punctuation.section.parens.end.java
+          pop: true
+        - include: parameters
+        - match: \S
+          scope: invalid.illegal.missing-parameter-end
+          pop: true
+    - include: throws
+    - include: annotation-default
+    - match: \{
+      scope: punctuation.section.block.begin.java
+      set:
+        - meta_scope: meta.method.java meta.method.body.java
+        - match: \}
+          scope: punctuation.section.block.end.java
+          pop: true
+        - include: code-block
+    - include: any_POP
+
+  throws:
+    - match: \bthrows\b
+      scope: keyword.declaration.throws.java
+      push:
+      - - meta_scope: meta.method.throws.java
+        - match: \,
+          scope: punctuation.separator.comma.java
+          push: object-type-reference
+        - include: any_POP
+      - object-type-reference
+
+  # Stand-along uppercase id, either type or constant.
+  # Should be used only inside code blocks.
+  uppercase-identifiers:
+    # Popular JDK classes
+    - match: \b(?:UUID|UR[LI])\b
+      scope: support.class.java
+      push: after-object-type
+    # Generic type variable
+    - match: \b\p{Lu}\b
+      scope: support.class.java
+      push: after-object-type
+    # Uppercase constants
+    - match: \b{{uppercase_id}}
+      scope: constant.other.java
+
+  # Stand-alone type, maybe type of the variable or class object reference.
+  # Should be used only inside code blocks.
+  object-types:
+    # Here the match is more complex than 'before_fqn'.
+    # In code block we can't simply distinguish package from variable.
+    - match: (?=\b(?:{{lowercase_id}}\.)+\p{Lu})
+      push: [after-object-type, object-type-fqn]
+    - match: \b{{classcase_id}}\b
+      scope: support.class.java
+      push: after-object-type
+
+  object-type-fqn:
+    - meta_scope: meta.path.java
+    - include: package
+    - match: '{{classcase_id}}'
+      scope: support.class.java
+      pop: true
+    - include: any_POP
+
+  after-object-type:
+    - match: (?=<)
+      set: [array-brackets, generic-type-invocation]
+    - match: \.(?!\.)
+      scope: punctuation.accessor.dot.java
+      set:
+        - match: (?=<)
+          set: generic-type-invocation
+        - match: (?:(class)\b|({{uppercase_id}}))
+          captures:
+            1: variable.language.java
+            2: constant.other.java
+          pop: true
+        - match: '{{classcase_id}}'
+          scope: support.class.java
+          set: after-object-type
+        - include: any_POP
+    - include: array-brackets
+
+  # Used in 'throws' and generic bounds
+  object-type-reference:
+    - match: '{{before_fqn}}'
+      set:
+        - meta_scope: meta.path.java
+        - include: package
+        - include: object-type-reference-no-fqn
+    - include: object-type-reference-no-fqn
+
+  object-type-reference-no-fqn:
+    - match: '{{classcase_id}}'
+      scope: support.class.java
+      set: after-object-type-reference
+    - include: any_POP
+
+  after-object-type-reference:
+    - match: (?=<)
+      set: generic-type-invocation
+    - match: \.
+      scope: punctuation.accessor.dot.java
+      set: object-type-reference-no-fqn
+    - include: any_POP
+
+  # Used in method's and generic's parameters
+  object-and-array-types:
+    - match: '{{before_fqn}}'
+      push:
+        - meta_scope: meta.path.java
+        - include: package
+        - include: object-and-array-types-no-fqn
+    - match: \b({{primitives}})(?=\s*\[)
+      scope: storage.type.primitive.java
+      push: array-brackets
+    - match: \b{{classcase_id}}
+      scope: support.class.java
+      push: after-object-and-array-types
+
+  object-and-array-types-no-fqn:
+    - match: '{{classcase_id}}'
+      scope: support.class.java
+      set: after-object-and-array-types
+    - include: any_POP
+
+  after-object-and-array-types:
+    - match: (?=<)
+      set: [array-brackets, generic-type-invocation]
+    - match: \.(?!\.)
+      scope: punctuation.accessor.dot.java
+      set: object-and-array-types-no-fqn
+    - include: array-brackets
+
+  # Used in class-level 'extends' and 'implements'
+  inherited-object-type-reference:
+    - match: '{{before_fqn}}'
+      set:
+        - meta_scope: meta.path.java
+        - match: '{{lowercase_id}}'
+          scope: entity.other.inherited-class.package.java
+        - include: punctuation-accessor-dot
+        - include: inherited-object-type-reference-no-fqn
+    - include: inherited-object-type-reference-no-fqn
+
+  inherited-object-type-reference-no-fqn:
+    - match: (?!class|extends|implements|interface){{id}}
+      scope: entity.other.inherited-class.java
+      set: after-inherited-object-type-reference
+    - include: any_POP
+
+  after-inherited-object-type-reference:
+    - match: (?=<)
+      set: generic-type-invocation
+    - match: \.
+      scope: punctuation.accessor.dot.java
+      set: inherited-object-type-reference-no-fqn
+    - include: any_POP
+
+  generic-type-declaration:
+    - match: <
+      scope: punctuation.definition.generic.begin.java
+      push: generic-type-parameter
+    - include: any_POP
+
+  generic-type-terminator:
+    - include: illegal-semicolon
+    # These characters can't appear in a generic. If we've matched
+    # them then someone forgot to close it.
+    - match: (?=[{}()])
+      pop: true
+    - match: '>'
+      scope: punctuation.definition.generic.end.java
+      pop: true
+
+  generic-type-parameter:
+    - meta_scope: meta.generic.declaration.java
+    - match: \b{{id}}\b
+      scope: variable.parameter.type.java
+      push: generic-type-bounds
+    - include: generic-type-terminator
+
+  generic-type-bounds:
+    - match: (,)|(?=>)
+      captures:
+        1: punctuation.separator.comma.java
+      pop: true
+    - match: \bextends\b
+      scope: keyword.declaration.extends.java
+      push: [generic-type-extends-multiple-bounds, object-type-reference]
+    - match: \bsuper\b
+      scope: keyword.declaration.super.java
+      push: object-type-reference
+
+  generic-type-extends-multiple-bounds:
+    - match: '&'
+      scope: keyword.operator.multiple-bounds.java
+      set: [generic-type-extends-multiple-bounds, object-type-reference]
+    - include: any_POP
+
+  generic-type-invocation:
+    - match: <
+      scope: punctuation.definition.generic.begin.java
+      set: generic-type-argument
+    - include: any_POP
+
+  generic-type-argument:
+    - meta_scope: meta.generic.java
+    - match: \?
+      scope: keyword.operator.wildcard.java
+      push: generic-type-bounds
+    - include: generic-type-terminator
+    - include: object-and-array-types
+    - include: punctuation-separator-comma
+
+  annotation-default:
+    - match: \bdefault\b
+      scope: keyword.declaration.default.java
+      push:
+        - meta_scope: meta.annotation.default.java
+        - match: (?=;)
+          pop: true
+        - include: code
+
+  parameters:
+    - match: \bfinal\b
+      scope: storage.modifier.java
+    - include: annotations
+    - include: primitive-types
+    - include: object-and-array-types
+    - match: \.\.\.
+      scope: keyword.operator.variadic.java
+    - match: '{{id}}'
+      scope: variable.parameter.java
+      push: array-brackets
+    - include: punctuation-separator-comma
+
+  lambdas:
+    - match: (?={{lambda_lookahead}})
+      push: lambda-params
+
+  lambda-params:
+    - meta_scope: meta.function.anonymous.parameters.java
+    - match: \(
+      scope: punctuation.section.parens.begin.java
+      set:
+        - meta_scope: meta.function.anonymous.parameters.java
+        - match: \)
+          scope: punctuation.section.parens.end.java
+          set: lambda-arrow
+        - include: parameters
+    - match: '{{id}}'
+      scope: variable.parameter.java
+      set: lambda-arrow
+
+  lambda-arrow:
+    - match: ->
+      scope: storage.type.function.anonymous.java
+      set:
+        - meta_scope: meta.function.anonymous.body.java
+        - match: (?=[)};])
+          pop: true
+        - include: code
+
+  parens:
+    - match: \(
+      scope: punctuation.section.parens.begin.java
+      push:
+        - meta_scope: meta.parens.java
+        - match: \)
+          scope: punctuation.section.parens.end.java
+          pop: true
+        - include: illegal-parens-terminators
+        - include: code
+
+  declaration-statement-parens:
+    - match: \(
+      scope: punctuation.section.parens.begin.java
+      set:
+        - meta_scope: meta.parens.java
+        - match: \)
+          scope: punctuation.section.parens.end.java
+          pop: true
+        - include: illegal-open-block
+        - include: code-block
+    - include: any_POP
+
+  primitive-types:
+    - match: \b{{primitives}}\b
+      scope: storage.type.primitive.java
+      push: array-brackets
+
+  var-type:
+    - match: \bvar\b
+      scope: storage.type.var.java
+
+  array-brackets:
+    - match: \[\s*\]
+      scope: storage.modifier.array.java
+    - include: any_POP
+
+  static-assignment:
+    - match: \=
+      scope: keyword.operator.assignment.java
+      set:
+        - meta_scope: meta.assignment.rhs.java
+        - match: (?=[,;])
+          pop: true
+        - include: before-next-field
+        - include: code
+        - include: stray-parens
+    - include: any_POP
+
+  assignment:
+    - match: ([|&^*/+-]\=|\=(?!=))
+      scope: keyword.operator.assignment.java
+      push:
+        - meta_scope: meta.assignment.rhs.java
+        - match: (?=;|\)|\}|,)
+          pop: true
+        - include: code
+  static-code-block:
+    - match: \{
+      scope: punctuation.section.block.begin.java
+      push:
+        - meta_scope: meta.static.body.java
+        - match: \}
+          scope: punctuation.section.block.end.java
+          pop: true
+        - include: code-block
+  storage-modifiers:
+    - match: \b{{storage_modifiers}}\b
+      scope: storage.modifier.java
+  stray-braces:
+    - match: \}
+      scope: invalid.illegal.stray-brace-end
+  stray-parens:
+    - match: \)
+      scope: invalid.illegal.stray-parens-end
+
+  strings:
+    - match: \"
+      scope: punctuation.definition.string.begin.java
+      push:
+        - meta_include_prototype: false
+        - meta_scope: string.quoted.double.java
+        - match: \"
+          scope: punctuation.definition.string.end.java
+          pop: true
+        - include: strings-common
+    - match: \'
+      scope: punctuation.definition.string.begin.java
+      push:
+        - meta_include_prototype: false
+        - meta_scope: string.quoted.single.java
+        - match: \'
+          scope: punctuation.definition.string.end.java
+          pop: true
+        - include: strings-common
+
+  strings-common:
+    - match: \n
+      scope: invalid.illegal.newline.java
+      pop: true
+    - match: \\.
+      scope: constant.character.escape.java
+
+  module:
+    - match: (?=\b(?:open\s+)?module\b)
+      push:
+      - - meta_scope: meta.module.java
+        - include: immediate_POP
+      - - match: \bopen\b
+          scope: storage.modifier.java
+        - match: \bmodule\b
+          scope: storage.type.java
+          set: [module-body, module-identifier-scope, module-identifier]
+
+  module-identifier-scope:
+    - meta_scope: meta.module.identifier.java
+    - include: immediate_POP
+
+  module-identifier:
+    - match: '{{id}}'
+      set:
+        - - meta_scope: entity.name.module.java
+          - include: immediate_POP
+        - dot-separated-identifier
+    - include: any_POP
+
+  module-body:
+    - match: \{
+      scope: punctuation.section.braces.begin.java
+      set:
+        - meta_scope: meta.module.body.java
+        - include: module-body-content
+        - match: \}
+          scope: punctuation.section.braces.end.java
+          pop: true
+    - include: any_POP
+
+  module-body-content:
+    - match: \bexports\b
+      scope: keyword.other.module.exports.java
+      push: [exports-statement-scope, exports-or-opens-statement]
+    - match: \bopens\b
+      scope: keyword.other.module.opens.java
+      push: [opens-statement-scope, exports-or-opens-statement]
+    - match: \brequires\b
+      scope: keyword.other.module.requires.java
+      push: requires-statement
+    - match: \buses\b
+      scope: keyword.other.module.uses.java
+      push: [uses-statement-scope, object-type-reference]
+    - match: \bprovides\b
+      scope: keyword.other.module.provides.java
+      push: [provides-statement-scope, provides-with-statement, object-type-reference]
+    - include: punctuation-terminator-semicolon
+
+  # Should always come before module/package patterns
+  module-statement-terminator:
+    - match: (?=[;\}])
+      pop: true
+    - match: (?=\b(?:requires|exports|uses|provides|opens)\b)
+      pop: true
+
+  support-type-module:
+    - match: '{{id}}'
+      push:
+        - - meta_scope: support.type.module.java
+          - include: immediate_POP
+        - dot-separated-identifier
+
+  exports-statement-scope:
+    - meta_scope: meta.exports.java
+    - include: immediate_POP
+
+  opens-statement-scope:
+    - meta_scope: meta.opens.java
+    - include: immediate_POP
+
+  exports-or-opens-statement:
+    - match: \bto\b
+      scope: keyword.other.module.to.java
+      set:
+        - include: module-statement-terminator
+        - include: support-type-module
+        - include: punctuation-separator-comma
+    - include: module-statement-terminator
+    - match: '{{id}}'
+      push:
+        - - meta_scope: support.type.package.java
+          - include: immediate_POP
+        - dot-separated-identifier
+
+  requires-statement:
+    - meta_scope: meta.requires.java
+    - match: \btransitive\b
+      scope: keyword.other.module.transitive.java
+    - include: module-statement-terminator
+    - include: support-type-module
+
+  uses-statement-scope:
+    - meta_scope: meta.uses.java
+    - include: immediate_POP
+
+  provides-statement-scope:
+    - meta_scope: meta.provides.java
+    - include: immediate_POP
+
+  provides-with-statement:
+    - match: \bwith\b
+      scope: keyword.other.module.with.java
+      set:
+        - - match: \,
+            scope: punctuation.separator.comma.java
+            push: object-type-reference
+          - include: any_POP
+        - object-type-reference
+    - include: any_POP
diff --git a/java/vendor/gr.tmTheme b/java/vendor/gr.tmTheme
new file mode 100644
index 0000000..c4ab8f1
--- /dev/null
+++ b/java/vendor/gr.tmTheme
@@ -0,0 +1,566 @@
+<?xml version="1.0" encoding="UTF-8"?>

+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

+<plist version="1.0">

+<dict>

+	<key>author</key>

+	<string>Template: Chris Kempson, Scheme: Alexandre Gavioli (https://github.com/Alexx2/)</string>

+	<key>name</key>

+	<string>Base16 Grayscale Light</string>

+	<key>semanticClass</key>

+	<string>theme.base16.grayscale-light</string>

+	<key>colorSpaceName</key>

+	<string>sRGB</string>

+	<key>gutterSettings</key>

+	<dict>

+		<key>background</key>

+		<string>#e3e3e3</string>

+		<key>divider</key>

+		<string>#e3e3e3</string>

+		<key>foreground</key>

+		<string>#ababab</string>

+		<key>selectionBackground</key>

+		<string>#b9b9b9</string>

+		<key>selectionForeground</key>

+		<string>#525252</string>

+	</dict>

+	<key>settings</key>

+	<array>

+		<dict>

+			<key>settings</key>

+			<dict>

+				<key>background</key>

+				<string>#f7f7f7</string>

+				<key>caret</key>

+				<string>#464646</string>

+				<key>foreground</key>

+				<string>#464646</string>

+				<key>invisibles</key>

+				<string>#ababab</string>

+				<key>lineHighlight</key>

+				<string>#ababab55</string>

+				<key>selection</key>

+				<string>#b9b9b9</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Text</string>

+			<key>scope</key>

+			<string>variable.parameter.function</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#222222</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Comments</string>

+			<key>scope</key>

+			<string>comment, punctuation.definition.comment</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#777777</string>

+				<key>fontStyle</key>

+				<string>bold</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Punctuation</string>

+			<key>scope</key>

+			<string>punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#111111</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Delimiters</string>

+			<key>scope</key>

+			<string>none</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#222222</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Operators</string>

+			<key>scope</key>

+			<string>keyword.operator</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#222222</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Keywords</string>

+			<key>scope</key>

+			<string>keyword</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#333333</string>

+				<key>fontStyle</key>

+				<string>bold</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Variables</string>

+			<key>scope</key>

+			<string>variable</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#555555</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Functions</string>

+			<key>scope</key>

+			<string>entity.name.function, meta.require, support.function.any-method, variable.function, variable.annotation, support.macro</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#444444</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Labels</string>

+			<key>scope</key>

+			<string>entity.name.label</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#5e5e5e</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Classes</string>

+			<key>scope</key>

+			<string>support.class, entity.name.class, entity.name.type.class</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#666666</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Classes</string>

+			<key>scope</key>

+			<string>meta.class</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#101010</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Methods</string>

+			<key>scope</key>

+			<string>keyword.other.special-method</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#444444</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Storage</string>

+			<key>scope</key>

+			<string>storage</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#444444</string>

+				<key>fontStyle</key>

+				<string>bold</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Support</string>

+			<key>scope</key>

+			<string>support.function</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#868686</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Strings, Inherited Class</string>

+			<key>scope</key>

+			<string>string, constant.other.symbol, entity.other.inherited-class</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#333333</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Integers</string>

+			<key>scope</key>

+			<string>constant.numeric</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#000000</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Floats</string>

+			<key>scope</key>

+			<string>none</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#000000</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Boolean</string>

+			<key>scope</key>

+			<string>none</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#222222</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Constants</string>

+			<key>scope</key>

+			<string>constant</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#000000</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Tags</string>

+			<key>scope</key>

+			<string>entity.name.tag</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#7c7c7c</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Attributes</string>

+			<key>scope</key>

+			<string>entity.other.attribute-name</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#999999</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Attribute IDs</string>

+			<key>scope</key>

+			<string>entity.other.attribute-name.id, punctuation.definition.entity</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#686868</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Selector</string>

+			<key>scope</key>

+			<string>meta.selector</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#747474</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Values</string>

+			<key>scope</key>

+			<string>none</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#999999</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Headings</string>

+			<key>scope</key>

+			<string>markup.heading punctuation.definition.heading, entity.name.section</string>

+			<key>settings</key>

+			<dict>

+				<key>fontStyle</key>

+				<string></string>

+				<key>foreground</key>

+				<string>#686868</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Units</string>

+			<key>scope</key>

+			<string>keyword.other.unit</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#999999</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Bold</string>

+			<key>scope</key>

+			<string>markup.bold, punctuation.definition.bold</string>

+			<key>settings</key>

+			<dict>

+				<key>fontStyle</key>

+				<string>bold</string>

+				<key>foreground</key>

+				<string>#a0a0a0</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Italic</string>

+			<key>scope</key>

+			<string>markup.italic, punctuation.definition.italic</string>

+			<key>settings</key>

+			<dict>

+				<key>fontStyle</key>

+				<string>italic</string>

+				<key>foreground</key>

+				<string>#747474</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Code</string>

+			<key>scope</key>

+			<string>markup.raw.inline</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#8e8e8e</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Link Text</string>

+			<key>scope</key>

+      <string>string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#7c7c7c</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Link Url</string>

+			<key>scope</key>

+			<string>meta.link</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#999999</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Lists</string>

+			<key>scope</key>

+			<string>markup.list</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#7c7c7c</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Quotes</string>

+			<key>scope</key>

+			<string>markup.quote</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#999999</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Separator</string>

+			<key>scope</key>

+			<string>meta.separator</string>

+			<key>settings</key>

+			<dict>

+				<key>background</key>

+				<string>#b9b9b9</string>

+				<key>foreground</key>

+				<string>#464646</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Inserted</string>

+			<key>scope</key>

+			<string>markup.inserted</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#8e8e8e</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Deleted</string>

+			<key>scope</key>

+			<string>markup.deleted</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#7c7c7c</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Changed</string>

+			<key>scope</key>

+			<string>markup.changed</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#747474</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Colors</string>

+			<key>scope</key>

+			<string>constant.other.color</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#868686</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Regular Expressions</string>

+			<key>scope</key>

+			<string>string.regexp</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#868686</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Escape Characters</string>

+			<key>scope</key>

+			<string>constant.character.escape</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#868686</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Embedded</string>

+			<key>scope</key>

+			<string>punctuation.section.embedded, variable.interpolation</string>

+			<key>settings</key>

+			<dict>

+				<key>foreground</key>

+				<string>#747474</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Illegal</string>

+			<key>scope</key>

+			<string>invalid.illegal</string>

+			<key>settings</key>

+			<dict>

+				<key>background</key>

+				<string>#7c7c7c</string>

+				<key>foreground</key>

+				<string>#101010</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Broken</string>

+			<key>scope</key>

+			<string>invalid.broken</string>

+			<key>settings</key>

+			<dict>

+				<key>background</key>

+				<string>#999999</string>

+				<key>foreground</key>

+				<string>#f7f7f7</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Deprecated</string>

+			<key>scope</key>

+			<string>invalid.deprecated</string>

+			<key>settings</key>

+			<dict>

+				<key>background</key>

+				<string>#5e5e5e</string>

+				<key>foreground</key>

+				<string>#101010</string>

+			</dict>

+		</dict>

+		<dict>

+			<key>name</key>

+			<string>Unimplemented</string>

+			<key>scope</key>

+			<string>invalid.unimplemented</string>

+			<key>settings</key>

+			<dict>

+				<key>background</key>

+				<string>#ababab</string>

+				<key>foreground</key>

+				<string>#101010</string>

+			</dict>

+		</dict>

+	</array>

+	<key>uuid</key>

+	<string>uuid</string>

+</dict>

+</plist>

diff --git a/java/wltd b/java/wltd
new file mode 100755
index 0000000..e385b5c
--- /dev/null
+++ b/java/wltd
@@ -0,0 +1,5 @@
+#!/bin/sh
+echo diff code : text
+diff <(ls code/ | sed 's/.java$//g; /~/d') <(ls text/ | sed 's/.typ$//g; /~/d')
+echo diff code : output
+diff <(ls code/ | sed 's/.java$//g; /~/d') <(ls output/ | sed 's/.typ$//g; /~/d')