diff --git a/MV3302ClassCode/build.xml b/MV3302ClassCode/build.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4b6b0b8e4389d7b08cf0dd93ad45804cacaab227
--- /dev/null
+++ b/MV3302ClassCode/build.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See commented blocks below for -->
+<!-- some examples of how to customize the build. -->
+<!-- (If you delete it and reopen the project it will be recreated.) -->
+<!-- By default, only the Clean and Build commands use this build script. -->
+<!-- Commands such as Run, Debug, and Test only use this build script if -->
+<!-- the Compile on Save feature is turned off for the project. -->
+<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
+<!-- in the project's Project Properties dialog box.-->
+<project name="MV3302" default="default" basedir=".">
+    <description>Builds, tests, and runs the project MV3302.</description>
+    <import file="nbproject/build-impl.xml"/>
+    <!--
+
+    There exist several targets which are by default empty and which can be 
+    used for execution of your tasks. These targets are usually executed 
+    before and after some main targets. They are: 
+
+      -pre-init:                 called before initialization of project properties
+      -post-init:                called after initialization of project properties
+      -pre-compile:              called before javac compilation
+      -post-compile:             called after javac compilation
+      -pre-compile-single:       called before javac compilation of single file
+      -post-compile-single:      called after javac compilation of single file
+      -pre-compile-test:         called before javac compilation of JUnit tests
+      -post-compile-test:        called after javac compilation of JUnit tests
+      -pre-compile-test-single:  called before javac compilation of single JUnit test
+      -post-compile-test-single: called after javac compilation of single JUunit test
+      -pre-jar:                  called before JAR building
+      -post-jar:                 called after JAR building
+      -post-clean:               called after cleaning build products
+
+    (Targets beginning with '-' are not intended to be called on their own.)
+
+    Example of inserting an obfuscator after compilation could look like this:
+
+        <target name="-post-compile">
+            <obfuscate>
+                <fileset dir="${build.classes.dir}"/>
+            </obfuscate>
+        </target>
+
+    For list of available properties check the imported 
+    nbproject/build-impl.xml file. 
+
+
+    Another way to customize the build is by overriding existing main targets.
+    The targets of interest are: 
+
+      -init-macrodef-javac:     defines macro for javac compilation
+      -init-macrodef-junit:     defines macro for junit execution
+      -init-macrodef-debug:     defines macro for class debugging
+      -init-macrodef-java:      defines macro for class execution
+      -do-jar:                  JAR building
+      run:                      execution of project 
+      -javadoc-build:           Javadoc generation
+      test-report:              JUnit report generation
+
+    An example of overriding the target for project execution could look like this:
+
+        <target name="run" depends="MV3302-impl.jar">
+            <exec dir="bin" executable="launcher.exe">
+                <arg file="${dist.jar}"/>
+            </exec>
+        </target>
+
+    Notice that the overridden target depends on the jar target and not only on 
+    the compile target as the regular run target does. Again, for a list of available 
+    properties which you can use, check the target you are overriding in the
+    nbproject/build-impl.xml file. 
+
+    -->
+</project>
diff --git a/MV3302ClassCode/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar b/MV3302ClassCode/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar
new file mode 100644
index 0000000000000000000000000000000000000000..174d1fcfa7325a5f9f1927055b019f286d066c0c
Binary files /dev/null and b/MV3302ClassCode/lib/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar differ
diff --git a/MV3302ClassCode/lib/Simkit/simkit-doc.zip b/MV3302ClassCode/lib/Simkit/simkit-doc.zip
new file mode 100644
index 0000000000000000000000000000000000000000..aac0e347ed6295a5bfe6e7bd688594dc9547cbd9
Binary files /dev/null and b/MV3302ClassCode/lib/Simkit/simkit-doc.zip differ
diff --git a/MV3302ClassCode/lib/Simkit/simkit-src.zip b/MV3302ClassCode/lib/Simkit/simkit-src.zip
new file mode 100644
index 0000000000000000000000000000000000000000..d59c83ccf374e741a098a485f27a04874f8cee69
Binary files /dev/null and b/MV3302ClassCode/lib/Simkit/simkit-src.zip differ
diff --git a/MV3302ClassCode/lib/Simkit/simkit.jar b/MV3302ClassCode/lib/Simkit/simkit.jar
new file mode 100644
index 0000000000000000000000000000000000000000..eef6be93d76b7ccd5113feb91c67e118be777312
Binary files /dev/null and b/MV3302ClassCode/lib/Simkit/simkit.jar differ
diff --git a/MV3302ClassCode/lib/nblibraries.properties b/MV3302ClassCode/lib/nblibraries.properties
new file mode 100644
index 0000000000000000000000000000000000000000..c6a0aa4e7958d9351a1674fdc7cb7321a53dedb9
--- /dev/null
+++ b/MV3302ClassCode/lib/nblibraries.properties
@@ -0,0 +1,11 @@
+libs.CopyLibs.classpath=\
+    ${base}/CopyLibs/org-netbeans-modules-java-j2seproject-copylibstask.jar
+libs.CopyLibs.displayName=CopyLibs Task
+libs.CopyLibs.prop-version=3.0
+libs.Simkit.classpath=\
+    ${base}/Simkit/simkit.jar
+libs.Simkit.displayName=Simkit
+libs.Simkit.javadoc=\
+    ${base}/Simkit/simkit-doc.zip!//
+libs.Simkit.src=\
+    ${base}/Simkit/simkit-src.zip!//
diff --git a/MV3302ClassCode/nbproject/build-impl.xml b/MV3302ClassCode/nbproject/build-impl.xml
new file mode 100644
index 0000000000000000000000000000000000000000..90f7b24ef66c88a0406e6caf7138a2f4703d0089
--- /dev/null
+++ b/MV3302ClassCode/nbproject/build-impl.xml
@@ -0,0 +1,1796 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+
+For the purpose of easier reading the script
+is divided into following sections:
+
+  - initialization
+  - compilation
+  - jar
+  - execution
+  - debugging
+  - javadoc
+  - test compilation
+  - test execution
+  - test debugging
+  - applet
+  - cleanup
+
+        -->
+<project xmlns:if="ant:if" xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" xmlns:unless="ant:unless" basedir=".." default="default" name="MV3302-impl">
+    <fail message="Please build using Ant 1.8.0 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.8.0"/>
+            </not>
+        </condition>
+    </fail>
+    <target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
+    <!-- 
+                ======================
+                INITIALIZATION SECTION 
+                ======================
+            -->
+    <target name="-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init" name="-init-private">
+        <property file="nbproject/private/config.properties"/>
+        <property file="nbproject/private/configs/${config}.properties"/>
+        <property file="nbproject/private/private.properties"/>
+    </target>
+    <target name="-pre-init-libraries">
+        <property location=".\lib\nblibraries.properties" name="libraries.path"/>
+        <dirname file="${libraries.path}" property="libraries.dir.nativedirsep"/>
+        <pathconvert dirsep="/" property="libraries.dir">
+            <path path="${libraries.dir.nativedirsep}"/>
+        </pathconvert>
+        <basename file="${libraries.path}" property="libraries.basename" suffix=".properties"/>
+        <available file="${libraries.dir}/${libraries.basename}-private.properties" property="private.properties.available"/>
+    </target>
+    <target depends="-pre-init-libraries" if="private.properties.available" name="-init-private-libraries">
+        <loadproperties encoding="ISO-8859-1" srcfile="${libraries.dir}/${libraries.basename}-private.properties">
+            <filterchain>
+                <replacestring from="$${base}" to="${libraries.dir}"/>
+                <escapeunicode/>
+            </filterchain>
+        </loadproperties>
+    </target>
+    <target depends="-pre-init,-init-private,-init-private-libraries" name="-init-libraries">
+        <loadproperties encoding="ISO-8859-1" srcfile="${libraries.path}">
+            <filterchain>
+                <replacestring from="$${base}" to="${libraries.dir}"/>
+                <escapeunicode/>
+            </filterchain>
+        </loadproperties>
+    </target>
+    <target depends="-pre-init,-init-private,-init-libraries" name="-init-user">
+        <property file="${user.properties.file}"/>
+        <!-- The two properties below are usually overridden -->
+        <!-- by the active platform. Just a fallback. -->
+        <property name="default.javac.source" value="1.8"/>
+        <property name="default.javac.target" value="1.8"/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-libraries,-init-user" name="-init-project">
+        <property file="nbproject/configs/${config}.properties"/>
+        <property file="nbproject/project.properties"/>
+    </target>
+    <target name="-init-modules-supported">
+        <condition property="modules.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-8](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-modules-supported" if="modules.supported.internal" name="-init-macrodef-modulename">
+        <macrodef name="modulename" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute name="property"/>
+            <attribute name="sourcepath"/>
+            <sequential>
+                <loadresource property="@{property}" quiet="true">
+                    <javaresource classpath="@{sourcepath}" name="module-info.java" parentFirst="false"/>
+                    <filterchain>
+                        <stripjavacomments/>
+                        <linecontainsregexp>
+                            <regexp pattern="module .* \{"/>
+                        </linecontainsregexp>
+                        <tokenfilter>
+                            <linetokenizer/>
+                            <replaceregex flags="s" pattern="(\s*module\s+)(\S*)(\s*\{.*)" replace="\2"/>
+                        </tokenfilter>
+                        <striplinebreaks/>
+                    </filterchain>
+                </loadresource>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-modules-supported,-init-macrodef-modulename" if="modules.supported.internal" name="-init-source-module-properties">
+        <fail message="Java 9 support requires Ant 1.10.0 or higher.">
+            <condition>
+                <not>
+                    <antversion atleast="1.10.0"/>
+                </not>
+            </condition>
+        </fail>
+        <j2seproject3:modulename property="module.name" sourcepath="${src.dir}"/>
+        <condition property="named.module.internal">
+            <and>
+                <isset property="module.name"/>
+                <length length="0" string="${module.name}" when="greater"/>
+            </and>
+        </condition>
+        <condition property="unnamed.module.internal">
+            <not>
+                <isset property="named.module.internal"/>
+            </not>
+        </condition>
+        <property name="javac.modulepath" value=""/>
+        <property name="run.modulepath" value="${javac.modulepath}"/>
+        <property name="module.build.classes.dir" value="${build.classes.dir}"/>
+        <property name="debug.modulepath" value="${run.modulepath}"/>
+        <property name="javac.upgrademodulepath" value=""/>
+        <property name="run.upgrademodulepath" value="${javac.upgrademodulepath}"/>
+        <condition else="" property="javac.systemmodulepath.cmd.line.arg" value="--system '${javac.systemmodulepath}'">
+            <and>
+                <isset property="javac.systemmodulepath"/>
+                <length length="0" string="${javac.systemmodulepath}" when="greater"/>
+            </and>
+        </condition>
+        <property name="dist.jlink.dir" value="${dist.dir}/jlink"/>
+        <property name="dist.jlink.output" value="${dist.jlink.dir}/${application.title}"/>
+        <property name="module.name" value=""/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-init-macrodef-property,-init-modules-supported" name="-do-init">
+        <property name="platform.java" value="${java.home}/bin/java"/>
+        <available file="${manifest.file}" property="manifest.available"/>
+        <condition property="splashscreen.available">
+            <and>
+                <not>
+                    <equals arg1="${application.splash}" arg2="" trim="true"/>
+                </not>
+                <available file="${application.splash}"/>
+            </and>
+        </condition>
+        <condition property="main.class.available">
+            <and>
+                <isset property="main.class"/>
+                <not>
+                    <equals arg1="${main.class}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="profile.available">
+            <and>
+                <isset property="javac.profile"/>
+                <length length="0" string="${javac.profile}" when="greater"/>
+                <not>
+                    <matches pattern="1\.[0-7](\..*)?" string="${javac.source}"/>
+                </not>
+            </and>
+        </condition>
+        <condition property="do.archive">
+            <or>
+                <not>
+                    <istrue value="${jar.archive.disabled}"/>
+                </not>
+                <istrue value="${not.archive.disabled}"/>
+            </or>
+        </condition>
+        <condition property="do.archive+manifest.available">
+            <and>
+                <isset property="manifest.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+main.class.available">
+            <and>
+                <isset property="main.class.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+splashscreen.available">
+            <and>
+                <isset property="splashscreen.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="do.archive+profile.available">
+            <and>
+                <isset property="profile.available"/>
+                <istrue value="${do.archive}"/>
+            </and>
+        </condition>
+        <condition property="have.tests">
+            <or>
+                <available file="${test.src.dir}"/>
+            </or>
+        </condition>
+        <condition property="have.sources">
+            <or>
+                <available file="${src.dir}"/>
+            </or>
+        </condition>
+        <condition property="netbeans.home+have.tests">
+            <and>
+                <isset property="netbeans.home"/>
+                <isset property="have.tests"/>
+            </and>
+        </condition>
+        <condition property="no.javadoc.preview">
+            <and>
+                <isset property="javadoc.preview"/>
+                <isfalse value="${javadoc.preview}"/>
+            </and>
+        </condition>
+        <property name="run.jvmargs" value=""/>
+        <property name="run.jvmargs.ide" value=""/>
+        <property name="javac.compilerargs" value=""/>
+        <property name="work.dir" value="${basedir}"/>
+        <condition property="no.deps">
+            <and>
+                <istrue value="${no.dependencies}"/>
+            </and>
+        </condition>
+        <property name="javac.debug" value="true"/>
+        <property name="javadoc.preview" value="true"/>
+        <property name="application.args" value=""/>
+        <property name="source.encoding" value="${file.encoding}"/>
+        <property name="runtime.encoding" value="${source.encoding}"/>
+        <property name="manifest.encoding" value="${source.encoding}"/>
+        <condition property="javadoc.encoding.used" value="${javadoc.encoding}">
+            <and>
+                <isset property="javadoc.encoding"/>
+                <not>
+                    <equals arg1="${javadoc.encoding}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <property name="javadoc.encoding.used" value="${source.encoding}"/>
+        <property name="includes" value="**"/>
+        <property name="excludes" value=""/>
+        <property name="do.depend" value="false"/>
+        <condition property="do.depend.true">
+            <istrue value="${do.depend}"/>
+        </condition>
+        <path id="endorsed.classpath.path" path="${endorsed.classpath}"/>
+        <condition else="" property="endorsed.classpath.cmd.line.arg" value="-Xbootclasspath/p:'${toString:endorsed.classpath.path}'">
+            <and>
+                <isset property="endorsed.classpath"/>
+                <not>
+                    <equals arg1="${endorsed.classpath}" arg2="" trim="true"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="javac.profile.cmd.line.arg" value="-profile ${javac.profile}">
+            <isset property="profile.available"/>
+        </condition>
+        <condition else="false" property="jdkBug6558476">
+            <and>
+                <matches pattern="1\.[56]" string="${java.specification.version}"/>
+                <not>
+                    <os family="unix"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="javac.fork">
+            <or>
+                <istrue value="${jdkBug6558476}"/>
+                <istrue value="${javac.external.vm}"/>
+            </or>
+        </condition>
+        <property name="jar.index" value="false"/>
+        <property name="jar.index.metainf" value="${jar.index}"/>
+        <property name="copylibs.rebase" value="true"/>
+        <available file="${meta.inf.dir}/persistence.xml" property="has.persistence.xml"/>
+        <condition property="junit.available">
+            <or>
+                <available classname="org.junit.Test" classpath="${run.test.classpath}"/>
+                <available classname="junit.framework.Test" classpath="${run.test.classpath}"/>
+            </or>
+        </condition>
+        <condition property="testng.available">
+            <available classname="org.testng.annotations.Test" classpath="${run.test.classpath}"/>
+        </condition>
+        <condition property="junit+testng.available">
+            <and>
+                <istrue value="${junit.available}"/>
+                <istrue value="${testng.available}"/>
+            </and>
+        </condition>
+        <condition else="testng" property="testng.mode" value="mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <condition else="" property="testng.debug.mode" value="-mixed">
+            <istrue value="${junit+testng.available}"/>
+        </condition>
+        <property name="java.failonerror" value="true"/>
+    </target>
+    <target name="-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-do-init" name="-init-check">
+        <fail unless="src.dir">Must set src.dir</fail>
+        <fail unless="test.src.dir">Must set test.src.dir</fail>
+        <fail unless="build.dir">Must set build.dir</fail>
+        <fail unless="dist.dir">Must set dist.dir</fail>
+        <fail unless="build.classes.dir">Must set build.classes.dir</fail>
+        <fail unless="dist.javadoc.dir">Must set dist.javadoc.dir</fail>
+        <fail unless="build.test.classes.dir">Must set build.test.classes.dir</fail>
+        <fail unless="build.test.results.dir">Must set build.test.results.dir</fail>
+        <fail unless="build.classes.excludes">Must set build.classes.excludes</fail>
+        <fail unless="dist.jar">Must set dist.jar</fail>
+    </target>
+    <target name="-init-macrodef-property">
+        <macrodef name="property" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${@{value}}"/>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-source-module-properties" if="modules.supported.internal" name="-init-macrodef-javac-with-module">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.modulepath}" name="modulepath"/>
+            <attribute default="${javac.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${javac.processormodulepath}" name="processormodulepath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath" unless:set="named.module.internal"/>
+            <attribute default="${src.dir}" if:set="named.module.internal" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition property="warn.excludes.internal">
+                    <and>
+                        <isset property="named.module.internal"/>
+                        <length length="0" string="@{excludes}" trim="true" when="greater"/>
+                    </and>
+                </condition>
+                <echo if:set="warn.excludes.internal" level="warning" message="The javac excludes are not supported in the JDK 9 Named Module."/>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <condition property="processormodulepath.set">
+                    <resourcecount count="0" when="greater">
+                        <path>
+                            <pathelement path="@{processormodulepath}"/>
+                        </path>
+                    </resourcecount>
+                </condition>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <modulepath>
+                        <path path="@{modulepath}"/>
+                    </modulepath>
+                    <upgrademodulepath>
+                        <path path="@{upgrademodulepath}"/>
+                    </upgrademodulepath>
+                    <compilerarg line="${javac.systemmodulepath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg if:set="processormodulepath.set" value="--processor-module-path"/>
+                    <compilerarg if:set="processormodulepath.set" path="@{processormodulepath}"/>
+                    <compilerarg unless:set="processormodulepath.set" value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}" unless:set="processormodulepath.set"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg line="${annotation.processing.processor.options}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-source-module-properties" if="ap.supported.internal" name="-init-macrodef-javac-with-processors" unless="modules.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.modulepath}" name="modulepath"/>
+            <attribute default="${javac.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <mkdir dir="@{apgeneratedsrcdir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <compilerarg value="-processorpath"/>
+                    <compilerarg path="@{processorpath}:${empty.dir}"/>
+                    <compilerarg line="${ap.processors.internal}"/>
+                    <compilerarg line="${annotation.processing.processor.options}"/>
+                    <compilerarg value="-s"/>
+                    <compilerarg path="@{apgeneratedsrcdir}"/>
+                    <compilerarg line="${ap.proc.none.internal}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-source-module-properties" name="-init-macrodef-javac-without-processors" unless="ap.supported.internal">
+        <macrodef name="javac" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <attribute default="${javac.modulepath}" name="modulepath"/>
+            <attribute default="${javac.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${javac.processorpath}" name="processorpath"/>
+            <attribute default="${build.generated.sources.dir}/ap-source-output" name="apgeneratedsrcdir"/>
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="${javac.debug}" name="debug"/>
+            <attribute default="${empty.dir}" name="sourcepath"/>
+            <attribute default="${empty.dir}" name="gensrcdir"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.dir}/empty" name="empty.dir"/>
+                <mkdir dir="${empty.dir}"/>
+                <javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" fork="${javac.fork}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}" tempdir="${java.io.tmpdir}">
+                    <src>
+                        <dirset dir="@{gensrcdir}" erroronmissingdir="false">
+                            <include name="*"/>
+                        </dirset>
+                    </src>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <compilerarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <compilerarg line="${javac.profile.cmd.line.arg}"/>
+                    <compilerarg line="${javac.compilerargs}"/>
+                    <customize/>
+                </javac>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-javac-with-module,-init-macrodef-javac-with-processors,-init-macrodef-javac-without-processors" name="-init-macrodef-javac">
+        <macrodef name="depend" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${src.dir}" name="srcdir"/>
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <attribute default="${javac.classpath}" name="classpath"/>
+            <sequential>
+                <depend cache="${build.dir}/depcache" destdir="@{destdir}" excludes="${excludes}" includes="${includes}" srcdir="@{srcdir}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </depend>
+            </sequential>
+        </macrodef>
+        <macrodef name="force-recompile" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${build.classes.dir}" name="destdir"/>
+            <sequential>
+                <fail unless="javac.includes">Must set javac.includes</fail>
+                <pathconvert pathsep="${line.separator}" property="javac.includes.binary">
+                    <path>
+                        <filelist dir="@{destdir}" files="${javac.includes}"/>
+                    </path>
+                    <globmapper from="*.java" to="*.class"/>
+                </pathconvert>
+                <tempfile deleteonexit="true" property="javac.includesfile.binary"/>
+                <echo file="${javac.includesfile.binary}" message="${javac.includes.binary}"/>
+                <delete>
+                    <files includesfile="${javac.includesfile.binary}"/>
+                </delete>
+                <delete>
+                    <fileset file="${javac.includesfile.binary}"/>
+                </delete>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${junit.available}" name="-init-macrodef-junit-init">
+        <condition else="false" property="nb.junit.batch" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <not>
+                    <isset property="test.method"/>
+                </not>
+            </and>
+        </condition>
+        <condition else="false" property="nb.junit.single" value="true">
+            <and>
+                <istrue value="${junit.available}"/>
+                <isset property="test.method"/>
+            </and>
+        </condition>
+    </target>
+    <target name="-init-test-properties">
+        <property name="test.binaryincludes" value="&lt;nothing&gt;"/>
+        <property name="test.binarytestincludes" value=""/>
+        <property name="test.binaryexcludes" value=""/>
+    </target>
+    <target depends="-init-modules-supported" if="modules.supported.internal" name="-init-macrodef-junit-prototype-with-module">
+        <macrodef name="junit-prototype" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <element name="customizePrototype" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <classpath>
+                        <path path="${run.test.classpath}"/>
+                    </classpath>
+                    <modulepath>
+                        <path path="${run.test.modulepath}"/>
+                    </modulepath>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="-ea"/>
+                    <jvmarg line="${run.test.jvmargs}"/>
+                    <customizePrototype/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-modules-supported" name="-init-macrodef-junit-prototype-without-module" unless="modules.supported.internal">
+        <macrodef name="junit-prototype" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <element name="customizePrototype" optional="true"/>
+            <sequential>
+                <property name="junit.forkmode" value="perTest"/>
+                <junit dir="${work.dir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" forkmode="${junit.forkmode}" showoutput="true" tempdir="${build.dir}">
+                    <syspropertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <classpath>
+                        <path path="${run.test.classpath}"/>
+                    </classpath>
+                    <formatter type="brief" usefile="false"/>
+                    <formatter type="xml"/>
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="-ea"/>
+                    <customizePrototype/>
+                </junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties,-init-macrodef-junit-prototype-with-module,-init-macrodef-junit-prototype-without-module" if="${nb.junit.single}" name="-init-macrodef-junit-single" unless="${nb.junit.batch}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-prototype>
+                    <customizePrototype>
+                        <test methods="@{testmethods}" name="@{testincludes}" todir="${build.test.results.dir}"/>
+                        <customize/>
+                    </customizePrototype>
+                </j2seproject3:junit-prototype>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-test-properties,-init-macrodef-junit-prototype-with-module,-init-macrodef-junit-prototype-without-module" if="${nb.junit.batch}" name="-init-macrodef-junit-batch" unless="${nb.junit.single}">
+        <macrodef name="junit" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit-prototype>
+                    <customizePrototype>
+                        <batchtest todir="${build.test.results.dir}">
+                            <fileset dir="${test.src.dir}" excludes="@{excludes},${excludes}" includes="@{includes}">
+                                <filename name="@{testincludes}"/>
+                            </fileset>
+                            <fileset dir="${build.test.classes.dir}" excludes="@{excludes},${excludes},${test.binaryexcludes}" includes="${test.binaryincludes}">
+                                <filename name="${test.binarytestincludes}"/>
+                            </fileset>
+                        </batchtest>
+                        <customize/>
+                    </customizePrototype>
+                </j2seproject3:junit-prototype>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-init,-init-macrodef-junit-single, -init-macrodef-junit-batch" if="${junit.available}" name="-init-macrodef-junit"/>
+    <target if="${testng.available}" name="-init-macrodef-testng">
+        <macrodef name="testng" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <condition else="" property="testng.methods.arg" value="@{testincludes}.@{testmethods}">
+                    <isset property="test.method"/>
+                </condition>
+                <union id="test.set">
+                    <fileset dir="${test.src.dir}" excludes="@{excludes},**/*.xml,${excludes}" includes="@{includes}">
+                        <filename name="@{testincludes}"/>
+                    </fileset>
+                </union>
+                <taskdef classname="org.testng.TestNGAntTask" classpath="${run.test.classpath}" name="testng"/>
+                <testng classfilesetref="test.set" failureProperty="tests.failed" listeners="org.testng.reporters.VerboseReporter" methods="${testng.methods.arg}" mode="${testng.mode}" outputdir="${build.test.results.dir}" suitename="MV3302" testname="TestNG tests" workingDir="${work.dir}">
+                    <xmlfileset dir="${build.test.classes.dir}" includes="@{testincludes}"/>
+                    <propertyset>
+                        <propertyref prefix="test-sys-prop."/>
+                        <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                    </propertyset>
+                    <classpath>
+                        <path path="${run.test.classpath}"/>
+                    </classpath>
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <customize/>
+                </testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-macrodef-test-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <echo>No tests executed.</echo>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng" if="${testng.available}" name="-init-macrodef-testng-impl">
+        <macrodef name="test-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element implicit="true" name="customize" optional="true"/>
+            <sequential>
+                <j2seproject3:testng excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize/>
+                </j2seproject3:testng>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-impl,-init-macrodef-junit-impl,-init-macrodef-testng-impl" name="-init-macrodef-test">
+        <macrodef name="test" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <sequential>
+                <j2seproject3:test-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customize>
+                </j2seproject3:test-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit" if="${junit.available}" name="-init-macrodef-junit-debug-impl">
+        <macrodef name="test-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <element name="customizeDebuggee" optional="true"/>
+            <sequential>
+                <j2seproject3:junit excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customize>
+                        <jvmarg value="-agentlib:jdwp=transport=${debug-transport},address=${jpda.address}"/>
+                        <customizeDebuggee/>
+                    </customize>
+                </j2seproject3:junit>
+            </sequential>
+        </macrodef>
+    </target>
+    <target if="${testng.available}" name="-init-macrodef-testng-debug">
+        <macrodef name="testng-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element name="customize2" optional="true"/>
+            <sequential>
+                <condition else="-testclass @{testClass}" property="test.class.or.method" value="-methods @{testClass}.@{testMethod}">
+                    <isset property="test.method"/>
+                </condition>
+                <condition else="-suitename MV3302 -testname @{testClass} ${test.class.or.method}" property="testng.cmd.args" value="@{testClass}">
+                    <matches pattern=".*\.xml" string="@{testClass}"/>
+                </condition>
+                <delete dir="${build.test.results.dir}" quiet="true"/>
+                <mkdir dir="${build.test.results.dir}"/>
+                <j2seproject3:debug classname="org.testng.TestNG" classpath="${debug.test.classpath}">
+                    <customizeDebuggee>
+                        <customize2/>
+                        <jvmarg value="-ea"/>
+                        <arg line="${testng.debug.mode}"/>
+                        <arg line="-d ${build.test.results.dir}"/>
+                        <arg line="-listener org.testng.reporters.VerboseReporter"/>
+                        <arg line="${testng.cmd.args}"/>
+                    </customizeDebuggee>
+                </j2seproject3:debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug" if="${testng.available}" name="-init-macrodef-testng-debug-impl">
+        <macrodef name="testng-debug-impl" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <element implicit="true" name="customize2" optional="true"/>
+            <sequential>
+                <j2seproject3:testng-debug testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2/>
+                </j2seproject3:testng-debug>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-junit-debug-impl" if="${junit.available}" name="-init-macrodef-test-debug-junit">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:test-debug-impl excludes="@{excludes}" includes="@{includes}" testincludes="@{testincludes}" testmethods="@{testmethods}">
+                    <customizeDebuggee>
+                        <jvmarg line="${run.jvmargs}"/>
+                        <jvmarg line="${run.jvmargs.ide}"/>
+                    </customizeDebuggee>
+                </j2seproject3:test-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-testng-debug-impl" if="${testng.available}" name="-init-macrodef-test-debug-testng">
+        <macrodef name="test-debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${includes}" name="includes"/>
+            <attribute default="${excludes}" name="excludes"/>
+            <attribute default="**" name="testincludes"/>
+            <attribute default="" name="testmethods"/>
+            <attribute default="${main.class}" name="testClass"/>
+            <attribute default="" name="testMethod"/>
+            <sequential>
+                <j2seproject3:testng-debug-impl testClass="@{testClass}" testMethod="@{testMethod}">
+                    <customize2>
+                        <syspropertyset>
+                            <propertyref prefix="test-sys-prop."/>
+                            <mapper from="test-sys-prop.*" to="*" type="glob"/>
+                        </syspropertyset>
+                    </customize2>
+                </j2seproject3:testng-debug-impl>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-test-debug-junit,-init-macrodef-test-debug-testng" name="-init-macrodef-test-debug"/>
+    <!--
+                pre NB7.2 profiling section; consider it deprecated
+            -->
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile, -profile-init-check" if="profiler.info.jvmargs.agent" name="profile-init"/>
+    <target if="profiler.info.jvmargs.agent" name="-profile-pre-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-post-init">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="profiler.info.jvmargs.agent" name="-profile-init-macrodef-profile">
+        <macrodef name="resolve">
+            <attribute name="name"/>
+            <attribute name="value"/>
+            <sequential>
+                <property name="@{name}" value="${env.@{value}}"/>
+            </sequential>
+        </macrodef>
+        <macrodef name="profile">
+            <attribute default="${main.class}" name="classname"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property environment="env"/>
+                <resolve name="profiler.current.path" value="${profiler.info.pathvar}"/>
+                <java classname="@{classname}" dir="${profiler.info.dir}" failonerror="${java.failonerror}" fork="true" jvm="${profiler.info.jvm}">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="${profiler.info.jvmargs.agent}"/>
+                    <jvmarg line="${profiler.info.jvmargs}"/>
+                    <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+                    <arg line="${application.args}"/>
+                    <classpath>
+                        <path path="${run.classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-profile-pre-init, init, -profile-post-init, -profile-init-macrodef-profile" if="profiler.info.jvmargs.agent" name="-profile-init-check">
+        <fail unless="profiler.info.jvm">Must set JVM to use for profiling in profiler.info.jvm</fail>
+        <fail unless="profiler.info.jvmargs.agent">Must set profiler agent JVM arguments in profiler.info.jvmargs.agent</fail>
+    </target>
+    <!--
+                end of pre NB7.2 profiling section
+            -->
+    <target depends="-init-debug-args" name="-init-macrodef-nbjpda">
+        <macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${main.class}" name="name"/>
+            <attribute default="${debug.modulepath}" name="modulepath"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <attribute default="" name="stopclassname"/>
+            <sequential>
+                <nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
+                    <modulepath>
+                        <path path="@{modulepath}"/>
+                    </modulepath>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                </nbjpdastart>
+            </sequential>
+        </macrodef>
+        <macrodef name="nbjpdareload" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${build.classes.dir}" name="dir"/>
+            <sequential>
+                <nbjpdareload>
+                    <fileset dir="@{dir}" includes="${fix.classes}">
+                        <include name="${fix.includes}*.class"/>
+                    </fileset>
+                </nbjpdareload>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-debug-args">
+        <condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
+            <os family="windows"/>
+        </condition>
+        <condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
+            <isset property="debug.transport"/>
+        </condition>
+    </target>
+    <target depends="-init-debug-args" name="-init-macrodef-debug">
+        <macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${module.name}" name="modulename"/>
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${debug.modulepath}" name="modulepath"/>
+            <attribute default="${debug.classpath}" name="classpath"/>
+            <element name="customizeDebuggee" optional="true"/>
+            <sequential>
+                <j2seproject1:java classname="@{classname}" classpath="@{classpath}" modulename="@{modulename}" modulepath="@{modulepath}">
+                    <customize>
+                        <jvmarg value="-agentlib:jdwp=transport=${debug-transport},address=${jpda.address}"/>
+                        <customizeDebuggee/>
+                    </customize>
+                </j2seproject1:java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-source-module-properties" if="named.module.internal" name="-init-macrodef-java-with-module">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="${module.name}" name="modulename"/>
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.modulepath}" name="modulepath"/>
+            <attribute default="${run.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true" module="@{modulename}">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <modulepath>
+                        <pathelement path="@{modulepath}"/>
+                        <pathelement location="${module.build.classes.dir}"/>
+                    </modulepath>
+                    <upgrademodulepath>
+                        <path path="@{upgrademodulepath}"/>
+                    </upgrademodulepath>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-source-module-properties" if="unnamed.module.internal" name="-init-macrodef-java-with-unnamed-module">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="" name="modulename"/>
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="${run.modulepath}" name="modulepath"/>
+            <attribute default="${run.upgrademodulepath}" name="upgrademodulepath"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <modulepath>
+                        <path path="@{modulepath}"/>
+                    </modulepath>
+                    <upgrademodulepath>
+                        <path path="@{upgrademodulepath}"/>
+                    </upgrademodulepath>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-source-module-properties" name="-init-macrodef-java-without-module" unless="modules.supported.internal">
+        <macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <attribute default="" name="modulename"/>
+            <attribute default="${main.class}" name="classname"/>
+            <attribute default="" name="modulepath"/>
+            <attribute default="${run.classpath}" name="classpath"/>
+            <attribute default="jvm" name="jvm"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <java classname="@{classname}" dir="${work.dir}" failonerror="${java.failonerror}" fork="true">
+                    <jvmarg line="${endorsed.classpath.cmd.line.arg}"/>
+                    <jvmarg value="-Dfile.encoding=${runtime.encoding}"/>
+                    <redirector errorencoding="${runtime.encoding}" inputencoding="${runtime.encoding}" outputencoding="${runtime.encoding}"/>
+                    <jvmarg line="${run.jvmargs}"/>
+                    <jvmarg line="${run.jvmargs.ide}"/>
+                    <classpath>
+                        <path path="@{classpath}"/>
+                    </classpath>
+                    <syspropertyset>
+                        <propertyref prefix="run-sys-prop."/>
+                        <mapper from="run-sys-prop.*" to="*" type="glob"/>
+                    </syspropertyset>
+                    <customize/>
+                </java>
+            </sequential>
+        </macrodef>
+    </target>
+    <target depends="-init-macrodef-java-with-module, -init-macrodef-java-with-unnamed-module, -init-macrodef-java-without-module" name="-init-macrodef-java"/>
+    <target name="-init-macrodef-copylibs">
+        <macrodef name="copylibs" uri="http://www.netbeans.org/ns/j2se-project/3">
+            <attribute default="${manifest.file}" name="manifest"/>
+            <element name="customize" optional="true"/>
+            <sequential>
+                <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+                <pathconvert property="run.classpath.without.build.classes.dir">
+                    <path path="${run.classpath}"/>
+                    <map from="${build.classes.dir.resolved}" to=""/>
+                </pathconvert>
+                <pathconvert pathsep=" " property="jar.classpath">
+                    <path path="${run.classpath.without.build.classes.dir}"/>
+                    <chainedmapper>
+                        <flattenmapper/>
+                        <filtermapper>
+                            <replacestring from=" " to="%20"/>
+                        </filtermapper>
+                        <globmapper from="*" to="lib/*"/>
+                    </chainedmapper>
+                </pathconvert>
+                <taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
+                <copylibs compress="${jar.compress}" excludeFromCopy="${copylibs.excludes}" index="${jar.index}" indexMetaInf="${jar.index.metainf}" jarfile="${dist.jar}" manifest="@{manifest}" manifestencoding="UTF-8" rebase="${copylibs.rebase}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
+                    <fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+                    <manifest>
+                        <attribute name="Class-Path" value="${jar.classpath}"/>
+                        <customize/>
+                    </manifest>
+                </copylibs>
+            </sequential>
+        </macrodef>
+    </target>
+    <target name="-init-presetdef-jar">
+        <presetdef name="jar" uri="http://www.netbeans.org/ns/j2se-project/1">
+            <jar compress="${jar.compress}" index="${jar.index}" jarfile="${dist.jar}" manifestencoding="UTF-8">
+                <j2seproject1:fileset dir="${build.classes.dir}" excludes="${dist.archive.excludes}"/>
+            </jar>
+        </presetdef>
+    </target>
+    <target name="-init-ap-cmdline-properties">
+        <property name="annotation.processing.enabled" value="true"/>
+        <property name="annotation.processing.processors.list" value=""/>
+        <property name="annotation.processing.processor.options" value=""/>
+        <property name="annotation.processing.run.all.processors" value="true"/>
+        <property name="javac.processorpath" value="${javac.classpath}"/>
+        <property name="javac.test.processorpath" value="${javac.test.classpath}"/>
+        <condition property="ap.supported.internal" value="true">
+            <not>
+                <matches pattern="1\.[0-5](\..*)?" string="${javac.source}"/>
+            </not>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties" if="ap.supported.internal" name="-init-ap-cmdline-supported">
+        <condition else="" property="ap.processors.internal" value="-processor ${annotation.processing.processors.list}">
+            <isfalse value="${annotation.processing.run.all.processors}"/>
+        </condition>
+        <condition else="" property="ap.proc.none.internal" value="-proc:none">
+            <isfalse value="${annotation.processing.enabled}"/>
+        </condition>
+    </target>
+    <target depends="-init-ap-cmdline-properties,-init-ap-cmdline-supported" name="-init-ap-cmdline">
+        <property name="ap.cmd.line.internal" value=""/>
+    </target>
+    <target depends="-pre-init,-init-private,-init-libraries,-init-user,-init-project,-do-init,-post-init,-init-check,-init-macrodef-property,-init-macrodef-javac,-init-macrodef-test,-init-macrodef-test-debug,-init-macrodef-nbjpda,-init-macrodef-debug,-init-macrodef-java,-init-presetdef-jar,-init-ap-cmdline" name="init"/>
+    <!--
+                ===================
+                COMPILATION SECTION
+                ===================
+            -->
+    <target name="-deps-jar-init" unless="built-jar.properties">
+        <property location="${build.dir}/built-jar.properties" name="built-jar.properties"/>
+        <delete file="${built-jar.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.jar.${basedir}" name="-warn-already-built-jar">
+        <echo level="warn" message="Cycle detected: MV3302 was already built"/>
+    </target>
+    <target depends="init,-deps-jar-init" name="deps-jar" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-jar.properties}" verbose="false"/>
+        <property file="${built-jar.properties}" prefix="already.built.jar."/>
+        <antcall target="-warn-already-built-jar"/>
+        <propertyfile file="${built-jar.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
+    <target depends="init" name="-check-automatic-build">
+        <available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
+    </target>
+    <target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
+        <antcall target="clean">
+            <param name="no.dependencies" value="true"/>
+        </antcall>
+    </target>
+    <target depends="init,deps-jar" name="-pre-pre-compile">
+        <mkdir dir="${build.classes.dir}"/>
+    </target>
+    <target name="-pre-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target if="do.depend.true" name="-compile-depend">
+        <pathconvert property="build.generated.subdirs">
+            <dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="*"/>
+            </dirset>
+        </pathconvert>
+        <j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile,-pre-compile, -copy-persistence-xml,-compile-depend" if="have.sources" name="-do-compile">
+        <j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
+        <copy todir="${build.classes.dir}">
+            <fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target if="has.persistence.xml" name="-copy-persistence-xml">
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy todir="${build.classes.dir}/META-INF">
+            <fileset dir="${meta.inf.dir}" includes="persistence.xml orm.xml"/>
+        </copy>
+    </target>
+    <target name="-post-compile">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
+    <target name="-pre-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile/>
+        <j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}, module-info.java" sourcepath="${src.dir}"/>
+    </target>
+    <target name="-post-compile-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
+    <!--
+                ====================
+                JAR BUILDING SECTION
+                ====================
+            -->
+    <target depends="init" name="-pre-pre-jar">
+        <dirname file="${dist.jar}" property="dist.jar.dir"/>
+        <mkdir dir="${dist.jar.dir}"/>
+    </target>
+    <target name="-pre-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile" name="-check-module-main-class">
+        <pathconvert property="main.class.file">
+            <string value="${main.class}"/>
+            <unpackagemapper from="*" to="*.class"/>
+        </pathconvert>
+        <condition property="do.module.main.class">
+            <and>
+                <isset property="main.class.available"/>
+                <available file="${build.classes.dir}/module-info.class"/>
+                <available file="${build.classes.dir}/${main.class.file}"/>
+                <isset property="libs.CopyLibs.classpath"/>
+                <available classname="org.netbeans.modules.java.j2seproject.moduletask.ModuleMainClass" classpath="${libs.CopyLibs.classpath}"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-check-module-main-class" if="do.module.main.class" name="-set-module-main-class">
+        <taskdef classname="org.netbeans.modules.java.j2seproject.moduletask.ModuleMainClass" classpath="${libs.CopyLibs.classpath}" name="modulemainclass"/>
+        <modulemainclass failonerror="false" mainclass="${main.class}" moduleinfo="${build.classes.dir}/module-info.class"/>
+    </target>
+    <target depends="init" if="do.archive" name="-do-jar-create-manifest" unless="manifest.available">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <touch file="${tmp.manifest.file}" verbose="false"/>
+    </target>
+    <target depends="init" if="do.archive+manifest.available" name="-do-jar-copy-manifest">
+        <tempfile deleteonexit="true" destdir="${build.dir}" property="tmp.manifest.file"/>
+        <copy encoding="${manifest.encoding}" file="${manifest.file}" outputencoding="UTF-8" tofile="${tmp.manifest.file}"/>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+main.class.available" name="-do-jar-set-mainclass">
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="Main-Class" value="${main.class}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+profile.available" name="-do-jar-set-profile">
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="Profile" value="${javac.profile}"/>
+        </manifest>
+    </target>
+    <target depends="init,-do-jar-create-manifest,-do-jar-copy-manifest" if="do.archive+splashscreen.available" name="-do-jar-set-splashscreen">
+        <basename file="${application.splash}" property="splashscreen.basename"/>
+        <mkdir dir="${build.classes.dir}/META-INF"/>
+        <copy failonerror="false" file="${application.splash}" todir="${build.classes.dir}/META-INF"/>
+        <manifest encoding="UTF-8" file="${tmp.manifest.file}" mode="update">
+            <attribute name="SplashScreen-Image" value="META-INF/${splashscreen.basename}"/>
+        </manifest>
+    </target>
+    <target depends="init,compile" name="-check-do-mkdist">
+        <condition property="do.mkdist">
+            <and>
+                <isset property="do.archive"/>
+                <isset property="libs.CopyLibs.classpath"/>
+                <not>
+                    <istrue value="${mkdist.disabled}"/>
+                </not>
+                <not>
+                    <available file="${build.classes.dir}/module-info.class"/>
+                </not>
+            </and>
+        </condition>
+    </target>
+    <target depends="init,-init-macrodef-copylibs,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-check-do-mkdist" if="do.mkdist" name="-do-jar-copylibs">
+        <j2seproject3:copylibs manifest="${tmp.manifest.file}"/>
+        <echo level="info">To run this application from the command line without Ant, try:</echo>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <echo level="info">java -jar "${dist.jar.resolved}"</echo>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-check-do-mkdist" if="do.archive" name="-do-jar-jar" unless="do.mkdist">
+        <j2seproject1:jar manifest="${tmp.manifest.file}"/>
+        <property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
+        <property location="${dist.jar}" name="dist.jar.resolved"/>
+        <condition else="${dist.jar.resolved}" property="jar.usage.message.class.path.replacement" value="">
+            <isset property="named.module.internal"/>
+        </condition>
+        <pathconvert property="run.classpath.with.dist.jar">
+            <path path="${run.classpath}"/>
+            <map from="${build.classes.dir.resolved}" to="${jar.usage.message.class.path.replacement}"/>
+        </pathconvert>
+        <pathconvert property="run.modulepath.with.dist.jar">
+            <path location="${dist.jar.resolved}"/>
+            <path path="${run.modulepath}"/>
+            <map from="${build.classes.dir.resolved}" to="${dist.jar.resolved}"/>
+        </pathconvert>
+        <condition else="${run.modulepath}" property="jar.usage.message.run.modulepath.with.dist.jar" value="${run.modulepath.with.dist.jar}">
+            <isset property="named.module.internal"/>
+        </condition>
+        <condition else="" property="jar.usage.message.module.path" value=" -p ${jar.usage.message.run.modulepath.with.dist.jar}">
+            <and>
+                <isset property="modules.supported.internal"/>
+                <length length="0" string="${jar.usage.message.run.modulepath.with.dist.jar}" when="greater"/>
+            </and>
+        </condition>
+        <condition else="" property="jar.usage.message.class.path" value=" -cp ${run.classpath.with.dist.jar}">
+            <length length="0" string="${run.classpath.with.dist.jar}" when="greater"/>
+        </condition>
+        <condition else="/${main.class}" property="jar.usage.message.main.class.class.selector" value="">
+            <isset property="do.module.main.class"/>
+        </condition>
+        <condition else=" ${main.class}" property="jar.usage.message.main.class" value=" -m ${module.name}${jar.usage.message.main.class.class.selector}">
+            <isset property="named.module.internal"/>
+        </condition>
+        <condition else="" property="jar.usage.message" value="To run this application from the command line without Ant, try:${line.separator}${platform.java}${jar.usage.message.module.path}${jar.usage.message.class.path}${jar.usage.message.main.class}">
+            <isset property="main.class.available"/>
+        </condition>
+        <condition else="debug" property="jar.usage.level" value="info">
+            <isset property="main.class.available"/>
+        </condition>
+        <echo level="${jar.usage.level}" message="${jar.usage.message}"/>
+    </target>
+    <target depends="-do-jar-copylibs" if="do.archive" name="-do-jar-delete-manifest">
+        <delete>
+            <fileset file="${tmp.manifest.file}"/>
+        </delete>
+    </target>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-jar,-do-jar-delete-manifest" name="-do-jar-without-libraries"/>
+    <target depends="init,compile,-pre-pre-jar,-pre-jar,-do-jar-create-manifest,-do-jar-copy-manifest,-do-jar-set-mainclass,-do-jar-set-profile,-do-jar-set-splashscreen,-do-jar-copylibs,-do-jar-delete-manifest" name="-do-jar-with-libraries"/>
+    <target name="-post-jar">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-jar,-set-module-main-class,-do-jar-without-libraries,-do-jar-with-libraries,-post-jar" name="-do-jar"/>
+    <target depends="init,compile,-pre-jar,-do-jar,-post-jar,deploy" description="Build JAR." name="jar"/>
+    <!--
+                =================
+                DEPLOY SECTION
+                =================
+            -->
+    <target name="-pre-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init" name="-check-jlink">
+        <condition property="do.jlink.internal">
+            <and>
+                <istrue value="${do.jlink}"/>
+                <isset property="do.archive"/>
+                <isset property="named.module.internal"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="init,-do-jar,-post-jar,-pre-deploy,-check-jlink" if="do.jlink.internal" name="-do-deploy">
+        <delete dir="${dist.jlink.dir}" failonerror="false" quiet="true"/>
+        <property name="jlink.launcher.name" value="${application.title}"/>
+        <condition else="${module.name}" property="jlink.add.modules" value="${module.name},${jlink.additionalmodules}">
+            <and>
+                <isset property="jlink.additionalmodules"/>
+                <length length="0" string="${jlink.additionalmodules}" when="greater"/>
+            </and>
+        </condition>
+        <condition property="jlink.do.strip.internal">
+            <and>
+                <isset property="jlink.strip"/>
+                <istrue value="${jlink.strip}"/>
+            </and>
+        </condition>
+        <condition property="jlink.do.additionalparam.internal">
+            <and>
+                <isset property="jlink.additionalparam"/>
+                <length length="0" string="${jlink.additionalparam}" when="greater"/>
+            </and>
+        </condition>
+        <condition property="jlink.do.launcher.internal">
+            <and>
+                <istrue value="${jlink.launcher}"/>
+                <isset property="main.class.available"/>
+            </and>
+        </condition>
+        <property name="platform.jlink" value="${jdk.home}/bin/jlink"/>
+        <property name="jlink.systemmodules.internal" value="${jdk.home}/jmods"/>
+        <exec executable="${platform.jlink}">
+            <arg value="--module-path"/>
+            <arg path="${jlink.systemmodules.internal}:${run.modulepath}:${dist.jar}"/>
+            <arg value="--add-modules"/>
+            <arg value="${jlink.add.modules}"/>
+            <arg if:set="jlink.do.strip.internal" value="--strip-debug"/>
+            <arg if:set="jlink.do.launcher.internal" value="--launcher"/>
+            <arg if:set="jlink.do.launcher.internal" value="${jlink.launcher.name}=${module.name}/${main.class}"/>
+            <arg if:set="jlink.do.additionalparam.internal" line="${jlink.additionalparam}"/>
+            <arg value="--output"/>
+            <arg value="${dist.jlink.output}"/>
+        </exec>
+    </target>
+    <target name="-post-deploy">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-do-jar,-post-jar,-pre-deploy,-do-deploy,-post-deploy" name="deploy"/>
+    <!--
+                =================
+                EXECUTION SECTION
+                =================
+            -->
+    <target depends="init,compile" description="Run a main class." name="run">
+        <j2seproject1:java>
+            <customize>
+                <arg line="${application.args}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <target name="-do-not-recompile">
+        <property name="javac.includes.binary" value=""/>
+    </target>
+    <target depends="init,compile-single" name="run-single">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}"/>
+    </target>
+    <target depends="init,compile-test-single" name="run-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
+    </target>
+    <!--
+                =================
+                DEBUGGING SECTION
+                =================
+            -->
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger">
+        <j2seproject1:nbjpdastart name="${debug.class}"/>
+    </target>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
+    </target>
+    <target depends="init,compile" name="-debug-start-debuggee">
+        <j2seproject3:debug>
+            <customizeDebuggee>
+                <arg line="${application.args}"/>
+            </customizeDebuggee>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile,-debug-start-debugger,-debug-start-debuggee" description="Debug project in IDE." if="netbeans.home" name="debug"/>
+    <target depends="init" if="netbeans.home" name="-debug-start-debugger-stepinto">
+        <j2seproject1:nbjpdastart stopclassname="${main.class}"/>
+    </target>
+    <target depends="init,compile,-debug-start-debugger-stepinto,-debug-start-debuggee" if="netbeans.home" name="debug-stepinto"/>
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-single">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}"/>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
+    <target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
+        <fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
+        <j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
+    </target>
+    <target depends="init,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
+    <target depends="init" name="-pre-debug-fix">
+        <fail unless="fix.includes">Must set fix.includes</fail>
+        <property name="javac.includes" value="${fix.includes}.java"/>
+    </target>
+    <target depends="init,-pre-debug-fix,compile-single" if="netbeans.home" name="-do-debug-fix">
+        <j2seproject1:nbjpdareload/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix" if="netbeans.home" name="debug-fix"/>
+    <!--
+                =================
+                PROFILING SECTION
+                =================
+            -->
+    <!--
+                pre NB7.2 profiler integration
+            -->
+    <target depends="profile-init,compile" description="Profile a project in the IDE." if="profiler.info.jvmargs.agent" name="-profile-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile/>
+    </target>
+    <target depends="profile-init,compile-single" description="Profile a selected class in the IDE." if="profiler.info.jvmargs.agent" name="-profile-single-pre72">
+        <fail unless="profile.class">Must select one file in the IDE or set profile.class</fail>
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="${profile.class}"/>
+    </target>
+    <target depends="profile-init,compile-single" if="profiler.info.jvmargs.agent" name="-profile-applet-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <profile classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </profile>
+    </target>
+    <target depends="-init-macrodef-junit,profile-init,compile-test-single" if="profiler.info.jvmargs.agent" name="-profile-test-single-pre72">
+        <fail unless="netbeans.home">This target only works when run from inside the NetBeans IDE.</fail>
+        <nbprofiledirect>
+            <classpath>
+                <path path="${run.test.classpath}"/>
+            </classpath>
+        </nbprofiledirect>
+        <j2seproject3:junit excludes="${excludes}" includes="${includes}" testincludes="${profile.class}" testmethods="">
+            <customize>
+                <jvmarg value="-agentlib:jdwp=transport=${debug-transport},address=${jpda.address}"/>
+                <env key="${profiler.info.pathvar}" path="${profiler.info.agentpath}:${profiler.current.path}"/>
+                <jvmarg value="${profiler.info.jvmargs.agent}"/>
+                <jvmarg line="${profiler.info.jvmargs}"/>
+                <classpath>
+                    <path path="${run.test.classpath}"/>
+                </classpath>
+            </customize>
+        </j2seproject3:junit>
+    </target>
+    <!--
+                end of pre NB72 profiling section
+            -->
+    <target if="netbeans.home" name="-profile-check">
+        <condition property="profiler.configured">
+            <or>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-agentpath:"/>
+                <contains casesensitive="true" string="${run.jvmargs.ide}" substring="-javaagent:"/>
+            </or>
+        </condition>
+    </target>
+    <target depends="-profile-check,-profile-pre72" description="Profile a project in the IDE." if="profiler.configured" name="profile" unless="profiler.info.jvmargs.agent">
+        <startprofiler/>
+        <antcall target="run"/>
+    </target>
+    <target depends="-profile-check,-profile-single-pre72" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-single" unless="profiler.info.jvmargs.agent">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-single"/>
+    </target>
+    <target depends="-profile-test-single-pre72" description="Profile a selected test in the IDE." name="profile-test-single"/>
+    <target depends="-profile-check" description="Profile a selected test in the IDE." if="profiler.configured" name="profile-test" unless="profiler.info.jvmargs">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <startprofiler/>
+        <antcall target="test-single"/>
+    </target>
+    <target depends="-profile-check" description="Profile a selected class in the IDE." if="profiler.configured" name="profile-test-with-main">
+        <fail unless="run.class">Must select one file in the IDE or set run.class</fail>
+        <startprofiler/>
+        <antcall target="run-test-with-main"/>
+    </target>
+    <target depends="-profile-check,-profile-applet-pre72" if="profiler.configured" name="profile-applet" unless="profiler.info.jvmargs.agent">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <startprofiler/>
+        <antcall target="run-applet"/>
+    </target>
+    <!--
+                ===============
+                JAVADOC SECTION
+                ===============
+            -->
+    <target depends="init" if="have.sources" name="-javadoc-build">
+        <mkdir dir="${dist.javadoc.dir}"/>
+        <condition else="" property="javadoc.endorsed.classpath.cmd.line.arg" value="-J${endorsed.classpath.cmd.line.arg}">
+            <and>
+                <isset property="endorsed.classpath.cmd.line.arg"/>
+                <not>
+                    <equals arg1="${endorsed.classpath.cmd.line.arg}" arg2=""/>
+                </not>
+            </and>
+        </condition>
+        <condition else="" property="bug5101868workaround" value="*.java">
+            <matches pattern="1\.[56](\..*)?" string="${java.version}"/>
+        </condition>
+        <condition else="" property="javadoc.html5.cmd.line.arg" value="-html5">
+            <and>
+                <isset property="javadoc.html5"/>
+                <available file="${jdk.home}${file.separator}lib${file.separator}jrt-fs.jar"/>
+            </and>
+        </condition>
+        <javadoc additionalparam="-J-Dfile.encoding=${file.encoding} ${javadoc.additionalparam}" author="${javadoc.author}" charset="UTF-8" destdir="${dist.javadoc.dir}" docencoding="UTF-8" encoding="${javadoc.encoding.used}" failonerror="true" noindex="${javadoc.noindex}" nonavbar="${javadoc.nonavbar}" notree="${javadoc.notree}" private="${javadoc.private}" source="${javac.source}" splitindex="${javadoc.splitindex}" use="${javadoc.use}" useexternalfile="true" version="${javadoc.version}" windowtitle="${javadoc.windowtitle}">
+            <classpath>
+                <path path="${javac.classpath}"/>
+            </classpath>
+            <fileset dir="${src.dir}" excludes="${bug5101868workaround},${excludes}" includes="${includes}">
+                <filename name="**/*.java"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/*.java"/>
+                <exclude name="*.java"/>
+            </fileset>
+            <arg line="${javadoc.endorsed.classpath.cmd.line.arg}"/>
+            <arg line="${javadoc.html5.cmd.line.arg}"/>
+        </javadoc>
+        <copy todir="${dist.javadoc.dir}">
+            <fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
+                <filename name="**/doc-files/**"/>
+            </fileset>
+            <fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
+                <include name="**/doc-files/**"/>
+            </fileset>
+        </copy>
+    </target>
+    <target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
+        <nbbrowse file="${dist.javadoc.dir}/index.html"/>
+    </target>
+    <target depends="init,-javadoc-build,-javadoc-browse" description="Build Javadoc." name="javadoc"/>
+    <!--
+                =========================
+                TEST COMPILATION SECTION
+                =========================
+            -->
+    <target depends="init,compile" if="have.tests" name="-pre-pre-compile-test">
+        <mkdir dir="${build.test.classes.dir}"/>
+    </target>
+    <target name="-pre-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="-init-source-module-properties" if="named.module.internal" name="-init-test-javac-module-properties-with-module">
+        <j2seproject3:modulename property="test.module.name" sourcepath="${test.src.dir}"/>
+        <condition else="${empty.dir}" property="javac.test.sourcepath" value="${test.src.dir}">
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+        <condition else="--patch-module ${module.name}=${test.src.dir} --add-reads ${module.name}=ALL-UNNAMED" property="javac.test.compilerargs" value="--add-reads ${test.module.name}=ALL-UNNAMED">
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-init-source-module-properties" if="named.module.internal" name="-init-test-run-module-properties">
+        <condition else="${module.name}" property="run.test.addexport.source.module.internal" value="${test.module.name}">
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+        <fileset dir="${build.test.classes.dir}" id="run.test.packages.internal" includes="**/*.class"/>
+        <property location="${build.test.classes.dir}" name="build.test.classes.dir.abs.internal"/>
+        <pathconvert pathsep=" " property="run.test.addexports.internal" refid="run.test.packages.internal">
+            <chainedmapper>
+                <regexpmapper from="^(.*)\Q${file.separator}\E.*\.class$$" to="\1"/>
+                <filtermapper>
+                    <uniqfilter/>
+                    <replacestring from="${build.test.classes.dir.abs.internal}" to=""/>
+                </filtermapper>
+                <cutdirsmapper dirs="1"/>
+                <packagemapper from="*" to="--add-exports ${run.test.addexport.source.module.internal}/*=ALL-UNNAMED"/>
+            </chainedmapper>
+        </pathconvert>
+        <condition else="--patch-module ${module.name}=${build.test.classes.dir} --add-modules ${module.name} --add-reads ${module.name}=ALL-UNNAMED ${run.test.addexports.internal}" property="run.test.jvmargs" value="--add-modules ${test.module.name} --add-reads ${test.module.name}=ALL-UNNAMED ${run.test.addexports.internal}">
+            <and>
+                <isset property="test.module.name"/>
+                <length length="0" string="${test.module.name}" when="greater"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-init-source-module-properties" name="-init-test-module-properties-without-module" unless="named.module.internal">
+        <property name="javac.test.sourcepath" value="${empty.dir}"/>
+        <property name="javac.test.compilerargs" value=""/>
+        <property name="run.test.jvmargs" value=""/>
+    </target>
+    <target depends="-init-test-javac-module-properties-with-module,-init-test-module-properties-without-module" name="-init-test-module-properties"/>
+    <target if="do.depend.true" name="-compile-test-depend">
+        <j2seproject3:depend classpath="${javac.test.classpath}" destdir="${build.test.classes.dir}" srcdir="${test.src.dir}"/>
+    </target>
+    <target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test,-compile-test-depend" if="have.tests" name="-do-compile-test">
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${javac.test.sourcepath}" srcdir="${test.src.dir}">
+            <customize>
+                <compilerarg line="${javac.test.compilerargs}"/>
+            </customize>
+        </j2seproject3:javac>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test,-do-compile-test,-post-compile-test" name="compile-test"/>
+    <target name="-pre-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-jar,compile,-init-test-module-properties,-pre-pre-compile-test,-pre-compile-test-single" if="have.tests" name="-do-compile-test-single">
+        <fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
+        <j2seproject3:force-recompile destdir="${build.test.classes.dir}"/>
+        <j2seproject3:javac apgeneratedsrcdir="${build.test.classes.dir}" classpath="${javac.test.classpath}" debug="true" destdir="${build.test.classes.dir}" excludes="" includes="${javac.includes}, module-info.java" modulepath="${javac.test.modulepath}" processorpath="${javac.test.processorpath}" sourcepath="${test.src.dir}" srcdir="${test.src.dir}">
+            <customize>
+                <compilerarg line="${javac.test.compilerargs}"/>
+            </customize>
+        </j2seproject3:javac>
+        <copy todir="${build.test.classes.dir}">
+            <fileset dir="${test.src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
+        </copy>
+    </target>
+    <target name="-post-compile-test-single">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,compile,-pre-pre-compile-test,-pre-compile-test-single,-do-compile-test-single,-post-compile-test-single" name="compile-test-single"/>
+    <!--
+                =======================
+                TEST EXECUTION SECTION
+                =======================
+            -->
+    <target depends="init" if="have.tests" name="-pre-test-run">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test,-init-test-run-module-properties,-pre-test-run" if="have.tests" name="-do-test-run">
+        <j2seproject3:test includes="${includes}" testincludes="**/*Test.java"/>
+    </target>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init" if="have.tests" name="test-report"/>
+    <target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
+    <target depends="init,compile-test,-pre-test-run,-do-test-run,test-report,-post-test-run,-test-browse" description="Run unit tests." name="test"/>
+    <target depends="init" if="have.tests" name="-pre-test-run-single">
+        <mkdir dir="${build.test.results.dir}"/>
+    </target>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-pre-test-run-single" if="have.tests" name="-do-test-run-single">
+        <fail unless="test.includes">Must select some files in the IDE or set test.includes</fail>
+        <j2seproject3:test excludes="" includes="${test.includes}" testincludes="${test.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-do-test-run-single-method">
+        <fail unless="test.class">Must select some files in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test excludes="" includes="${javac.includes}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single-method" if="have.tests" name="-post-test-run-single-method">
+        <fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
+    </target>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-pre-test-run-single,-do-test-run-single-method,-post-test-run-single-method" description="Run single unit test." name="test-single-method"/>
+    <!--
+                =======================
+                TEST DEBUGGING SECTION
+                =======================
+            -->
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testincludes="${javac.includes}"/>
+    </target>
+    <target depends="init,compile-test-single,-pre-test-run-single" if="have.tests" name="-debug-start-debuggee-test-method">
+        <fail unless="test.class">Must select one file in the IDE or set test.class</fail>
+        <fail unless="test.method">Must select some method in the IDE or set test.method</fail>
+        <j2seproject3:test-debug excludes="" includes="${javac.includes}" testClass="${test.class}" testMethod="${test.method}" testincludes="${test.class}" testmethods="${test.method}"/>
+    </target>
+    <target depends="init,compile-test" if="netbeans.home+have.tests" name="-debug-start-debugger-test">
+        <j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${test.class}"/>
+    </target>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test" name="debug-test"/>
+    <target depends="init,compile-test-single,-init-test-run-module-properties,-debug-start-debugger-test,-debug-start-debuggee-test-method" name="debug-test-method"/>
+    <target depends="debug-test-method" name="debug-single-method"/>
+    <target depends="init,-pre-debug-fix,compile-test-single" if="netbeans.home" name="-do-debug-fix-test">
+        <j2seproject1:nbjpdareload dir="${build.test.classes.dir}"/>
+    </target>
+    <target depends="init,-pre-debug-fix,-do-debug-fix-test" if="netbeans.home" name="debug-fix-test"/>
+    <!--
+                =========================
+                APPLET EXECUTION SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" name="run-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject1:java classname="sun.applet.AppletViewer">
+            <customize>
+                <arg value="${applet.url}"/>
+            </customize>
+        </j2seproject1:java>
+    </target>
+    <!--
+                =========================
+                APPLET DEBUGGING  SECTION
+                =========================
+            -->
+    <target depends="init,compile-single" if="netbeans.home" name="-debug-start-debuggee-applet">
+        <fail unless="applet.url">Must select one file in the IDE or set applet.url</fail>
+        <j2seproject3:debug classname="sun.applet.AppletViewer">
+            <customizeDebuggee>
+                <arg value="${applet.url}"/>
+            </customizeDebuggee>
+        </j2seproject3:debug>
+    </target>
+    <target depends="init,compile-single,-debug-start-debugger,-debug-start-debuggee-applet" if="netbeans.home" name="debug-applet"/>
+    <!--
+                ===============
+                CLEANUP SECTION
+                ===============
+            -->
+    <target name="-deps-clean-init" unless="built-clean.properties">
+        <property location="${build.dir}/built-clean.properties" name="built-clean.properties"/>
+        <delete file="${built-clean.properties}" quiet="true"/>
+    </target>
+    <target if="already.built.clean.${basedir}" name="-warn-already-built-clean">
+        <echo level="warn" message="Cycle detected: MV3302 was already built"/>
+    </target>
+    <target depends="init,-deps-clean-init" name="deps-clean" unless="no.deps">
+        <mkdir dir="${build.dir}"/>
+        <touch file="${built-clean.properties}" verbose="false"/>
+        <property file="${built-clean.properties}" prefix="already.built.clean."/>
+        <antcall target="-warn-already-built-clean"/>
+        <propertyfile file="${built-clean.properties}">
+            <entry key="${basedir}" value=""/>
+        </propertyfile>
+    </target>
+    <target depends="init" name="-do-clean">
+        <delete dir="${build.dir}"/>
+        <delete dir="${dist.jlink.output}"/>
+        <delete dir="${dist.dir}" followsymlinks="false" includeemptydirs="true"/>
+    </target>
+    <target name="-post-clean">
+        <!-- Empty placeholder for easier customization. -->
+        <!-- You can override this target in the ../build.xml file. -->
+    </target>
+    <target depends="init,deps-clean,-do-clean,-post-clean" description="Clean build products." name="clean"/>
+    <target name="-check-call-dep">
+        <property file="${call.built.properties}" prefix="already.built."/>
+        <condition property="should.call.dep">
+            <and>
+                <not>
+                    <isset property="already.built.${call.subproject}"/>
+                </not>
+                <available file="${call.script}"/>
+            </and>
+        </condition>
+    </target>
+    <target depends="-check-call-dep" if="should.call.dep" name="-maybe-call-dep">
+        <ant antfile="${call.script}" inheritall="false" target="${call.target}">
+            <propertyset>
+                <propertyref prefix="transfer."/>
+                <mapper from="transfer.*" to="*" type="glob"/>
+            </propertyset>
+        </ant>
+    </target>
+</project>
diff --git a/MV3302ClassCode/nbproject/genfiles.properties b/MV3302ClassCode/nbproject/genfiles.properties
new file mode 100644
index 0000000000000000000000000000000000000000..6b0ee15ced3b9b6e2359b799876539ae9ae9b6b0
--- /dev/null
+++ b/MV3302ClassCode/nbproject/genfiles.properties
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=78ca9dc9
+build.xml.script.CRC32=ca561466
+build.xml.stylesheet.CRC32=f85dc8f2@1.104.0.48
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=78ca9dc9
+nbproject/build-impl.xml.script.CRC32=69aa2bcf
+nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.104.0.48
diff --git a/MV3302ClassCode/nbproject/project.properties b/MV3302ClassCode/nbproject/project.properties
new file mode 100644
index 0000000000000000000000000000000000000000..8e152217fb8171e32c5ff2f261f011adfce1108e
--- /dev/null
+++ b/MV3302ClassCode/nbproject/project.properties
@@ -0,0 +1,97 @@
+annotation.processing.enabled=true
+annotation.processing.enabled.in.editor=false
+annotation.processing.processors.list=
+annotation.processing.run.all.processors=true
+annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
+application.title=MV3302
+application.vendor=dansl
+build.classes.dir=${build.dir}/classes
+build.classes.excludes=**/*.java,**/*.form
+# This directory is removed when the project is cleaned:
+build.dir=build
+build.generated.dir=${build.dir}/generated
+build.generated.sources.dir=${build.dir}/generated-sources
+# Only compile against the classpath explicitly listed here:
+build.sysclasspath=ignore
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+# Uncomment to specify the preferred debugger connection transport:
+#debug.transport=dt_socket
+debug.classpath=\
+    ${run.classpath}
+debug.modulepath=\
+    ${run.modulepath}
+debug.test.classpath=\
+    ${run.test.classpath}
+debug.test.modulepath=\
+    ${run.test.modulepath}
+# Files in build.classes.dir which should be excluded from distribution jar
+dist.archive.excludes=
+# This directory is removed when the project is cleaned:
+dist.dir=dist
+dist.jar=${dist.dir}/MV3302.jar
+dist.javadoc.dir=${dist.dir}/javadoc
+dist.jlink.dir=${dist.dir}/jlink
+dist.jlink.output=${dist.jlink.dir}/MV3302
+endorsed.classpath=
+excludes=
+includes=**
+jar.compress=false
+javac.classpath=\
+    ${libs.Simkit.classpath}
+# Space-separated list of extra javac options
+javac.compilerargs=
+javac.deprecation=false
+javac.external.vm=true
+javac.modulepath=
+javac.processormodulepath=
+javac.processorpath=\
+    ${javac.classpath}
+javac.source=17
+javac.target=17
+javac.test.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+javac.test.modulepath=\
+    ${javac.modulepath}
+javac.test.processorpath=\
+    ${javac.test.classpath}
+javadoc.additionalparam=
+javadoc.author=false
+javadoc.encoding=${source.encoding}
+javadoc.html5=false
+javadoc.noindex=false
+javadoc.nonavbar=false
+javadoc.notree=false
+javadoc.private=false
+javadoc.splitindex=true
+javadoc.use=true
+javadoc.version=false
+javadoc.windowtitle=
+# The jlink additional root modules to resolve
+jlink.additionalmodules=
+# The jlink additional command line parameters
+jlink.additionalparam=
+jlink.launcher=true
+jlink.launcher.name=MV3302
+main.class=mv3302.run.RunSimpleServer
+meta.inf.dir=${src.dir}/META-INF
+mkdist.disabled=true
+platform.active=default_platform
+run.classpath=\
+    ${javac.classpath}:\
+    ${build.classes.dir}
+# Space-separated list of JVM arguments used when running the project.
+# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
+# To set system properties for unit tests define test-sys-prop.name=value:
+run.jvmargs=
+run.modulepath=\
+    ${javac.modulepath}
+run.test.classpath=\
+    ${javac.test.classpath}:\
+    ${build.test.classes.dir}
+run.test.modulepath=\
+    ${javac.test.modulepath}
+source.encoding=UTF-8
+src.dir=src
+test.src.dir=test
diff --git a/MV3302ClassCode/nbproject/project.xml b/MV3302ClassCode/nbproject/project.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ada7c5b8f694760a85fd4af7350fe700b2157be9
--- /dev/null
+++ b/MV3302ClassCode/nbproject/project.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.java.j2seproject</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/j2se-project/3">
+            <name>MV3302</name>
+            <source-roots>
+                <root id="src.dir"/>
+            </source-roots>
+            <test-roots>
+                <root id="test.src.dir"/>
+            </test-roots>
+        </data>
+        <libraries xmlns="http://www.netbeans.org/ns/ant-project-libraries/1">
+            <definitions>.\lib\nblibraries.properties</definitions>
+        </libraries>
+    </configuration>
+</project>
diff --git a/MV3302ClassCode/newJavaFile.java b/MV3302ClassCode/newJavaFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..6592d790c595a50d850c33a8423a338e6cf56091
--- /dev/null
+++ b/MV3302ClassCode/newJavaFile.java
@@ -0,0 +1,18 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Other/File.java to edit this template
+ */
+
+/**
+ *
+ * @author dansl
+ */
+public class newJavaFile {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String args[]) {
+        // TODO code application logic here
+    }
+}
diff --git a/MV3302ClassCode/output.csv b/MV3302ClassCode/output.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/MV3302ClassCode/src/mv3302/ArrivalProcess.java b/MV3302ClassCode/src/mv3302/ArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..e17c72d3abacf78bd2e144d9af69ccfd4fe64e36
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/ArrivalProcess.java
@@ -0,0 +1,91 @@
+package mv3302;
+
+import simkit.SimEntityBase;
+import simkit.random.RandomVariate;
+
+/**
+ * A simple (yet useful) simulation component that schedules Arrival events
+ * using a <code>RandomVariate</code> instance for the times between Arrival
+ * events.<br>
+ * The state <code>numberArrivals></code> is incremented at each Arrival event.
+ *
+ * @author ahbuss
+ */
+public class ArrivalProcess extends SimEntityBase {
+
+    /**
+     * Generates interarrival times
+     */
+    private RandomVariate interarrivalTimeGenerator;
+
+    /**
+     * The number of arrivals at any given (sim) time
+     */
+    protected int numberArrivals;
+
+    /**
+     * Zero-argument constructor
+     */
+    public ArrivalProcess() {
+    }
+
+    /**
+     * Instantiate an Arrival Process with the given interarrivalTimeGenerator
+     *
+     * @param interarrivalTimeGenerator Given interarrivalTimeGenerator
+     */
+    public ArrivalProcess(RandomVariate interarrivalTimeGenerator) {
+        setInterarrivalTimeGenerator(interarrivalTimeGenerator);
+    }
+
+    /**
+     * Initialize numberArrivals to 0
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        numberArrivals = 0;
+    }
+
+    /**
+     * Schedule first Arrival event with delay of interarrival time
+     */
+    public void doRun() {
+        firePropertyChange("numberArrivals", getNumberArrivals());
+        waitDelay("Arrival", interarrivalTimeGenerator);
+    }
+
+    /**
+     * Increment numberArrivals<br>
+     * Schedule next Arrival event with delay of interarrival time
+     */
+    public void doArrival() {
+        int oldNumberArrivals = getNumberArrivals();
+        numberArrivals += 1;
+        firePropertyChange("numberArrivals", oldNumberArrivals, getNumberArrivals());
+
+        waitDelay("Arrival", interarrivalTimeGenerator);
+    }
+
+    /**
+     * @return the interarrivalTimeGenerator
+     */
+    public RandomVariate getInterarrivalTimeGenerator() {
+        return interarrivalTimeGenerator;
+    }
+
+    /**
+     * @param interarrivalTimeGenerator the interarrivalTimeGenerator to set
+     */
+    public void setInterarrivalTimeGenerator(RandomVariate interarrivalTimeGenerator) {
+        this.interarrivalTimeGenerator = interarrivalTimeGenerator;
+    }
+
+    /**
+     * @return the numberArrivals
+     */
+    public int getNumberArrivals() {
+        return numberArrivals;
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/Customer.java b/MV3302ClassCode/src/mv3302/Customer.java
new file mode 100644
index 0000000000000000000000000000000000000000..6aeeb8decbf6392ebe0953238fe9a55ecc7805a8
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/Customer.java
@@ -0,0 +1,52 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package mv3302;
+
+import simkit.Entity;
+
+/**
+ *Class represents a customer in a simulation. Assigns the customer with a respective 
+ * serviceTime and renegeTime
+ */
+public class Customer extends Entity {
+    
+    private double serviceTime;
+    
+    private double renegeTime;
+    
+    /**
+     * constructor method that assigns values of serviceTime and renegeTime to each customer
+     * @param serviceTime
+     * @param renegeTime
+     */
+    public Customer(double serviceTime, double renegeTime) {
+        super("Customer");
+        this.serviceTime = serviceTime;
+        this.renegeTime = renegeTime;
+    }
+
+    /**
+     * @return the serviceTime
+     */
+    public double getServiceTime() {
+        return serviceTime;
+    }
+
+    /**
+     * @return the renegeTime
+     */
+    public double getRenegeTime() {
+        return renegeTime;
+    }
+    
+    /**
+     * returns toString method with serviceTime and renegeTime
+     */
+    @Override
+    public String toString() {
+        return String.format("%s %,.4f %,.4f", super.toString(), serviceTime, renegeTime);
+    }
+    
+}
\ No newline at end of file
diff --git a/MV3302ClassCode/src/mv3302/CustomerArrivalProcess.java b/MV3302ClassCode/src/mv3302/CustomerArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..4957d31451f1363ece3facb4e55f1c95a4cf7ef5
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/CustomerArrivalProcess.java
@@ -0,0 +1,101 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package mv3302;
+
+import simkit.Entity;
+import simkit.random.RandomVariate;
+
+/**
+ * CustomerArrivalProcess class acts as the arrival process for the simulation
+ * extending the ArrivalProcess class. The class instantiates variables for the
+ * ServiceTime, RenegeTime, InterarrivalTime and numberArrivals
+ */
+public final class CustomerArrivalProcess extends ArrivalProcess {
+
+    private RandomVariate serviceTimeGenerator;
+
+    private RandomVariate renegeTimeGenerator;
+
+    private RandomVariate interarrivalTimeGenerator;
+
+    private int numberofArrivals;
+
+    /**
+     * Zero-argument constructor
+     */
+    public CustomerArrivalProcess() {
+        super();
+    }
+    
+    /**
+     * Constructor method that instantiates renege times and service times for
+     * each customer arrival
+     * @param renegeTimeGenerator
+     * @param interarrivalTimeGenerator
+     * @param serviceTimeGenerator
+     */
+    public CustomerArrivalProcess(RandomVariate renegeTimeGenerator, RandomVariate interarrivalTimeGenerator, RandomVariate serviceTimeGenerator) {
+        super(interarrivalTimeGenerator);
+        setServiceTimeGenerator(serviceTimeGenerator);
+        setRenegeTimeGenerator(renegeTimeGenerator);
+    }
+
+    /**
+     * Generates a customers serviceTime, renegeTime, iterates the total number
+     * of arrivals and schedules the customers arrival event
+     */
+    @Override
+    public void doArrival() {
+        super.doArrival();
+        double serviceTime = serviceTimeGenerator.generate();
+        double renegeTime = renegeTimeGenerator.generate();
+        Customer customer = new Customer(serviceTime, renegeTime);
+        waitDelay("Arrival", 0.0, customer);
+        numberofArrivals += 1;
+    }
+/**
+     * Does nothing, since this is only to be "heard"
+     * @param customer
+
+     */
+    public void doArrival(Customer customer) {
+    }
+    /**
+     * @return the serviceTimeGenerator
+     */
+    public RandomVariate getServiceTimeGenerator() {
+        return serviceTimeGenerator;
+    }
+
+    /**
+     * @param serviceTimeGenerator the serviceTimeGenerator to set
+     */
+    public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) {
+        this.serviceTimeGenerator = serviceTimeGenerator;
+    }
+
+    /**
+     * @return the renegeTimeGenerator
+     */
+    public RandomVariate getRenegeTimeGenerator() {
+        return renegeTimeGenerator;
+    }
+
+    /**
+     * @param renegeTimeGenerator the renegeTimeGenerator to set
+     */
+    public void setRenegeTimeGenerator(RandomVariate renegeTimeGenerator) {
+        this.renegeTimeGenerator = renegeTimeGenerator;
+    }
+
+    /**
+     * @return the numberArrivals
+     */
+    @Override
+    public int getNumberArrivals() {
+        return numberofArrivals;
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/EntityArrivalProcess.java b/MV3302ClassCode/src/mv3302/EntityArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..16fd60ce9866b9e792fedb2770bbc5f848f9f970
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/EntityArrivalProcess.java
@@ -0,0 +1,50 @@
+package mv3302;
+
+import simkit.Entity;
+import simkit.random.RandomVariate;
+
+/**
+ * Instantiates an <code>Entity</code> at each Arrival event and schedules an
+ * Arrival event with that as its argument
+ *
+ * @author ahbuss
+ */
+public class EntityArrivalProcess extends ArrivalProcess {
+
+    /**
+     * Zero-argument constructor
+     */
+    public EntityArrivalProcess() {
+        super();
+    }
+
+    /**
+     * Instantiate an <code>EntityArrivalProcess</code> with the given
+     * <code>interarrivalTimeGenerator</code>
+     *
+     * @param interarrivalTimeGenerator Given
+     * <code>interarrivalTimeGenerator</code>
+     */
+    public EntityArrivalProcess(RandomVariate interarrivalTimeGenerator) {
+        super(interarrivalTimeGenerator);
+    }
+
+    /**
+     * Schedule Arrival(Entity) with a new instance of <code>Entity</code><br>
+     */
+    @Override
+    public void doArrival() {
+        super.doArrival();
+        var entity = new Entity();
+        waitDelay("Arrival", 0.0, entity);
+    }
+
+    /**
+     * Does nothing, since this is only to be "heard"
+     *
+     * @param entity Given Entity
+     */
+    public void doArrival(Entity entity) {
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/EntityServer.java b/MV3302ClassCode/src/mv3302/EntityServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..531632f680d332daa8a5d1bc01b7522b0dcc4338
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/EntityServer.java
@@ -0,0 +1,235 @@
+package mv3302;
+
+import static java.lang.Double.NaN;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import simkit.Entity;
+import static simkit.Priority.HIGH;
+import simkit.SimEntityBase;
+import simkit.random.RandomVariate;
+
+/**
+ * Implementation of the multiple server queue model using<code>Entity</code>
+ * objects to represent individual customers. This allows the model to
+ * explicitly tally measures such as delay in queue and time in system.
+ *
+ * @author ahbuss
+ */
+public class EntityServer extends SimEntityBase {
+
+    /**
+     * Number of servers (k)
+     */
+    private int totalNumberServers;
+
+    /**
+     * Generates service times ({t<sub>S</sub>})
+     */
+    private RandomVariate serviceTimeGenerator;
+
+    /**
+     * # of available servers (S)
+     */
+    protected int numberAvailableServers;
+
+    /**
+     * Container of waiting customers (q)
+     */
+    protected SortedSet<Entity> queue;
+
+    /**
+     * time a given customer spends in queue (D - a transient state)
+     */
+    protected double delayInQueue;
+
+    /**
+     * time a given customer spends in the system (W - a transient state)
+     */
+    protected double timeInSystem;
+
+    /**
+     * Total number who complete service
+     */
+    protected int numberServed;
+
+    /**
+     * Instantiate an EntityServer with the given titalNumberServers and
+     * serviceTimeGenerator. Note: should call <code>this()</code> to ensure
+     * that <code>queue</code> is instantiated
+     *
+     * @param totalNumberServers
+     * @param serviceTimeGenerator
+     */
+    public EntityServer(int totalNumberServers, RandomVariate serviceTimeGenerator) {
+        this();
+        setTotalNumberServers(totalNumberServers);
+        setServiceTimeGenerator(serviceTimeGenerator);
+    }
+
+    /**
+     * Instantiate the <code>queue</code>state variable
+     */
+    public EntityServer() {
+        this.queue = new TreeSet<>();
+    }
+
+    /**
+     * Initialize state variables:<ul>
+     * <li>Empty <code>queue</code>
+     * <li>set numberAvailableServers to totalNumberServers
+     * <li>Set numberServed to 0
+     * <li>Set delayInQueue to NaN
+     * <li>Set timeInSystem to NaN </ul>
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        queue.clear();
+        numberAvailableServers = getTotalNumberServers();
+        numberServed = 0;
+        delayInQueue = NaN;
+        timeInSystem = NaN;
+    }
+
+    /**
+     * Fire property changes for time-varying states
+     */
+    public void doRun() {
+        firePropertyChange("queue", getQueue());
+        firePropertyChange("numberAvailableServers", getNumberAvailableServers());
+        firePropertyChange("numberServed", getNumberServed());
+    }
+
+    /**
+     * Stamp time and add customer to <code>queue</code><br>
+     * if available server, schedule StartService with delay of 0.0
+     *
+     * @param customer Arriving customer
+     */
+    public void doArrival(Entity customer) {
+        customer.stampTime();
+        var oldQueue = getQueue();
+        queue.add(customer);
+        firePropertyChange("queue", oldQueue, getQueue());
+
+        if (numberAvailableServers > 0) {
+            waitDelay("StartService", 0.0, HIGH);
+        }
+    }
+
+    /**
+     * Decrement numbervailableServers<br>
+     * Remove first customer from <code>queue</code><br>
+     * Compute delayInQueue as elapsed time<br>
+     * Schedule EndSrevice with delay generated by serviceTimeGenerator
+     */
+    public void doStartService() {
+        var oldNumberAvailableServers = getNumberAvailableServers();
+        numberAvailableServers -= 1;
+        firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
+
+        var oldQueue = getQueue();
+        var customer = queue.first();
+        queue.remove(customer);
+        firePropertyChange("queue", oldQueue, getQueue());
+
+        delayInQueue = customer.getElapsedTime();
+        firePropertyChange("delayInQueue", getDelayInQueue());
+
+        waitDelay("EndService", serviceTimeGenerator, customer);
+    }
+
+    /**
+     * Increment numberAvailableServers<br>
+     * Compute timeInSystem as customer's elapsedTime<br>
+     * Increment numberServed<br>
+     * If customer(s) in <code>queue</code>, schedule StartService with delay of 0.0
+     * 
+     * @param customer Given customer completing service 
+     */
+    public void doEndService(Entity customer) {
+        var oldNumberAvailableServers = getNumberAvailableServers();
+        numberAvailableServers += 1;
+        firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
+
+        timeInSystem = customer.getElapsedTime();
+        firePropertyChange("timeInSystem", getTimeInSystem());
+
+        var oldNumberServed = getNumberServed();
+        numberServed += 1;
+        firePropertyChange("numberServed", oldNumberServed, getNumberServed());
+
+        if (!queue.isEmpty()) {
+            waitDelay("StartService", 0.0, HIGH);
+        }
+
+    }
+
+    /**
+     * @return the totalNumberServers
+     */
+    public int getTotalNumberServers() {
+        return totalNumberServers;
+    }
+
+    /**
+     * @param totalNumberServers the totalNumberServers to set
+     * @throws IllegalArgumentException if totalNumberServers &le; 0
+     */
+    public void setTotalNumberServers(int totalNumberServers) {
+        if (totalNumberServers <= 0) {
+            throw new IllegalArgumentException("totalNumberServers must be > 0: " + totalNumberServers);
+        }
+        this.totalNumberServers = totalNumberServers;
+    }
+
+    /**
+     * @return the serviceTimeGenerator
+     */
+    public RandomVariate getServiceTimeGenerator() {
+        return serviceTimeGenerator;
+    }
+
+    /**
+     * @param serviceTimeGenerator the serviceTimeGenerator to set
+     */
+    public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) {
+        this.serviceTimeGenerator = serviceTimeGenerator;
+    }
+
+    /**
+     * @return the numberAvailableServers
+     */
+    public int getNumberAvailableServers() {
+        return numberAvailableServers;
+    }
+
+    /**
+     * @return the queue
+     */
+    public SortedSet<Entity> getQueue() {
+        return new TreeSet<>(queue);
+    }
+
+    /**
+     * @return the numberServed
+     */
+    public int getNumberServed() {
+        return numberServed;
+    }
+
+    /**
+     * @return the delayInQueue
+     */
+    public double getDelayInQueue() {
+        return delayInQueue;
+    }
+
+    /**
+     * @return the timeInSystem
+     */
+    public double getTimeInSystem() {
+        return timeInSystem;
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/Part.java b/MV3302ClassCode/src/mv3302/Part.java
new file mode 100644
index 0000000000000000000000000000000000000000..b884f866619052aa28be9b26e836603d14917199
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/Part.java
@@ -0,0 +1,44 @@
+package mv3302;
+
+import simkit.Entity;
+
+/**
+ * Instantiates a Part by extending the Entity Simkit base. Tracks the value of
+ * the totalDelayInQueue.
+ *
+ */
+public class Part extends Entity {
+
+    private double totalDelayInQueue;
+    private int next;
+
+    /**
+     * Zero Argument constructor method that makes a call to it's super.
+     * Initializes the value of the parts delay in queue time to 0.
+     *
+     */
+    public Part() {
+        this.totalDelayInQueue = 0.0;
+    }
+
+    /**
+     * Returns the totalDelayInQueue value
+     *
+     * @return
+     */
+    public double getTotalDelayInQueue() {
+        return this.totalDelayInQueue;
+    }
+
+    public void advance() {
+        this.next += 1;
+    }
+
+    /**
+     * Method passes in the increment delay value and adds it to the
+     * totalDelayInQueue variable
+     */
+    public void incrementDelayInQueue(double incrementDelay) {
+        this.totalDelayInQueue += incrementDelay;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/PartArrivalProcess.java b/MV3302ClassCode/src/mv3302/PartArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..30b3456d2d0353ab09173b56428d0963ee84ab75
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/PartArrivalProcess.java
@@ -0,0 +1,52 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package mv3302;
+
+import simkit.random.RandomVariate;
+
+/**
+ *PartArrivalProcess class extends ArrivalProcess instantiating an inter-arrival time
+ * for each part entered into the system. Arrives the part to the Arrival method of the
+ * super.
+ * @author dansl
+ */
+public class PartArrivalProcess extends ArrivalProcess{
+
+    public int numberPartsArrived;
+    /**
+     * Zero-argument constructor
+     */
+    public PartArrivalProcess() {
+        super();
+    }
+
+    /**
+     * Instantiate with the given parameters
+     *
+     * @param interarrivalTimes Given inter arrival times
+     */
+    public PartArrivalProcess(RandomVariate interarrivalTimes) {
+        super(interarrivalTimes);
+    }
+
+    /**
+     * Schedule next Arrival<br>
+     * Schedule Arrival(index)
+     */
+    @Override
+    public void doArrival() {
+        super.doArrival();
+        Part part = new Part();
+        numberPartsArrived +=1;
+        waitDelay("Arrival", 0.0, part, 0);
+    }
+
+    /**
+     * @return the numberPartsArrived
+     */
+    public int getNumberPartsArrived() {
+        return numberPartsArrived;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/ServerWithReneges.java b/MV3302ClassCode/src/mv3302/ServerWithReneges.java
new file mode 100644
index 0000000000000000000000000000000000000000..6c7d6e1131293018fc6d680ef806f9e99638a7fc
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/ServerWithReneges.java
@@ -0,0 +1,264 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package mv3302;
+
+import static java.lang.Double.NaN;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import static simkit.Priority.HIGH;
+import simkit.SimEntityBase;
+import simkit.random.RandomVariate;
+
+/**
+ * Implementation of the multiple server queue model using<code>Customer</code>
+ * objects to represent individual customers. This allows the model to
+ * explicitly tally measures such as delay in queue and time in system.
+ */
+public final class ServerWithReneges extends SimEntityBase {
+
+    /**
+     * Number of servers (k)
+     */
+    private int totalNumberServers;
+
+    /**
+     * # of available servers (S)
+     */
+    protected int numberAvailableServers;
+
+    /**
+     * Container of waiting customers (q)
+     */
+    protected SortedSet<Customer> queue;
+
+    /**
+     * time a given customer spends in queue (D - a transient state)
+     */
+    protected double delayInQueueServed = NaN;
+
+    /**
+     * time a given customer will spend in the queue before reneging
+     */
+    private double delayInQueueReneged;
+
+    /**
+     * time a given customer spends in the system (W - a transient state)
+     */
+    protected double timeInSystem = NaN;
+
+    private int numberReneges;
+
+    private int numberServed;
+
+    /**
+     * Generates service times ({t<sub>S</sub>})
+     */
+    private RandomVariate serviceTimeGenerator;
+
+    /**
+     * Instantiate a ServerWithReneges with the given totalNumberServers and
+     * serviceTimeGenerator. Note: should call <code>this()<</code> to ensure
+     * that <code>queue</code> is instantiated
+     *
+     * @param totalNumberServers
+     * @param serviceTimeGenerator
+     */
+    public ServerWithReneges(int totalNumberServers, RandomVariate serviceTimeGenerator) {
+        this();
+        setTotalNumberServers(totalNumberServers);
+        setServiceTimeGenerator(serviceTimeGenerator);
+    }
+
+    /**
+     * Instantiate the <code>queue</code>state variable
+     */
+    public ServerWithReneges() {
+        this.queue = new TreeSet<>();
+    }
+
+    /**
+     * Initialize state variables:<ul>
+     * <li>Empty <code>queue</code>
+     * <li>set numberAvailableServers to totalNumberServers
+     * <li>Set numberServed to 0
+     * <li>Set delayInQueue to NaN
+     * <li>Set timeInSystem to NaN </ul>
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        queue.clear();
+        numberAvailableServers = getTotalNumberServers();
+        delayInQueueServed = NaN;
+        delayInQueueReneged = 0.0;
+        timeInSystem = NaN;
+        numberReneges = 0;
+        numberServed = 0;
+    }
+
+    /**
+     * Fire property changes for time-varying states
+     */
+    public void doRun() {
+        firePropertyChange("queue", getQueue());
+        firePropertyChange("numberAvailableServers", getNumberAvailableServers());
+        firePropertyChange("numberReneges", getNumberReneges());
+    }
+
+    /**
+     * Stamp time and add customer to <code>queue</code><br>
+     * if available server, schedule StartService with delay of 0.0
+     *
+     * @param customer Arriving customer
+     */
+    public void doArrival(Customer customer) {
+        customer.stampTime();
+        SortedSet<Customer> oldQueue = getQueue();
+        queue.add(customer);
+        firePropertyChange("queue", oldQueue, getQueue());
+        waitDelay("Renege", 0.0, customer);
+        if (numberAvailableServers > 0) {
+            waitDelay("StartService", 0.0, HIGH);
+        }
+    }
+
+    /**
+     * Decrement numberAvailableServers<br>
+     * Remove first customer from <code>queue</code><br>
+     * Compute delayInQueueServed as elapsed time<br>
+     * Schedule EndService with delay generated by serviceTimeGenerator
+     */
+    public void doStartService() {
+        Customer customer = queue.first();
+        SortedSet<Customer> oldQueue = getQueue();
+        queue.remove(customer);
+        firePropertyChange("queue", oldQueue, getQueue());
+        int oldNumberAvailableServers = getNumberAvailableServers();
+        numberAvailableServers -= 1;
+        firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
+        delayInQueueServed = customer.getElapsedTime();
+        firePropertyChange("delayInQueueServed", getDelayInQueueServed());
+        interrupt("Renege", customer);
+        waitDelay("EndService", serviceTimeGenerator, customer);
+    }
+
+    /**
+     * Remove customer from the queue, increment the numberReneges, fires
+     * property changes for the total number of reneges, and captures
+     * delayInQueueReneged values as elapsedTime
+     */
+    public void doRenege(Customer customer) {
+        delayInQueueReneged = customer.getElapsedTime();
+        firePropertyChange("delayInQueueReneged", getDelayInQueueReneged());
+        SortedSet<Customer> oldQueue = getQueue();
+        queue.remove(customer);
+        firePropertyChange("queue", oldQueue, getQueue());
+        double oldNumberReneges = getNumberReneges();
+        numberReneges += 1;
+        firePropertyChange("numberReneges", oldNumberReneges, getNumberReneges());
+
+    }
+
+    /**
+     * Increment numberAvailableServers<br>
+     * Compute timeInSystem as customer's elapsedTime<br>
+     * Increment numberServed<br>
+     * If customer(s) in <code>queue</code>, schedule StartService with delay of
+     * 0.0
+     *
+     * @param customer Given customer completing service
+     */
+    public void doEndService(Customer customer) {
+        int oldNumberAvailableServers = getNumberAvailableServers();
+        numberAvailableServers += 1;
+        firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
+
+        timeInSystem = customer.getElapsedTime();
+        firePropertyChange("timeInSystem", getTimeInSystem());
+        numberServed += 1;
+        if (!queue.isEmpty()) {
+            waitDelay("StartService", 0.0, HIGH);
+        }
+    }
+
+    /**
+     * @return the totalNumberServers
+     */
+    public int getTotalNumberServers() {
+        return totalNumberServers;
+    }
+
+    /**
+     * @param totalNumberServers the totalNumberServers to set
+     * @throws IllegalArgumentException if totalNumberServers &le; 0
+     */
+    public void setTotalNumberServers(int totalNumberServers) {
+        if (totalNumberServers <= 0) {
+            throw new IllegalArgumentException("totalNumberServers must be > 0: " + totalNumberServers);
+        }
+        this.totalNumberServers = totalNumberServers;
+    }
+
+    /**
+     * @return the serviceTimeGenerator
+     */
+    public RandomVariate getServiceTimeGenerator() {
+        return serviceTimeGenerator;
+    }
+
+    /**
+     * @param serviceTimeGenerator the serviceTimeGenerator to set
+     */
+    public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) {
+        this.serviceTimeGenerator = serviceTimeGenerator;
+    }
+
+    /**
+     * @return the numberAvailableServers
+     */
+    public int getNumberAvailableServers() {
+        return numberAvailableServers;
+    }
+
+    /**
+     * @return the queue
+     */
+    public SortedSet<Customer> getQueue() {
+        return new TreeSet<>(queue);
+    }
+
+    /**
+     * @return the delayInQueue
+     */
+    public double getDelayInQueueServed() {
+        return delayInQueueServed;
+    }
+
+    /**
+     * @return the timeInSystem
+     */
+    public double getTimeInSystem() {
+        return timeInSystem;
+    }
+
+    /**
+     * @return the delayInQueueReneged
+     */
+    public double getDelayInQueueReneged() {
+        return delayInQueueReneged;
+    }
+
+    public double getNumberReneges() {
+        return numberReneges;
+    }
+
+    /**
+     * @return the numberServed
+     */
+    public int getNumberServed() {
+        return numberServed;
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/Ship.java b/MV3302ClassCode/src/mv3302/Ship.java
new file mode 100644
index 0000000000000000000000000000000000000000..485a5e8476158a692f43191e342726b20016a1fe
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/Ship.java
@@ -0,0 +1,57 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package mv3302;
+
+import simkit.Entity;
+
+/**
+ * The Ship class extends the Entity class from the Simkit library and
+ * represents a ship object that can be used in a simulation. It keeps track of
+ * the remaining time it takes to unload its cargo.
+ *
+ * @author dansl
+ */
+public final class Ship extends Entity {
+
+    protected double remainingUnloadingTime;
+
+    /**
+     * Constructs a new Ship object with the specified remaining unloading time.
+     *
+     * @param remainingUnloadingTime the time remaining to unload the ship's
+     * cargo.
+     */
+    public Ship(double remainingUnloadingTime) {
+        super();
+        setRemainingUnloadingTime(remainingUnloadingTime);
+    }
+
+    /**
+     * Reduces the remaining unloading time of the ship based on the elapsed
+     * time and the given rate.
+     * @param rate the rate at which the ship is being unloaded.
+     * @throws IllegalArgumentException if the rate is less than 0.
+     */
+    public void work(double rate) {
+        if (rate < 0.0) {
+            throw new IllegalArgumentException("Input Rate must be > 0.0: " + rate);
+        }
+        remainingUnloadingTime -= getElapsedTime() * rate;
+    }
+
+    /**
+     * @return the remainingUnloadingTime
+     */
+    public double getRemainingUnloadingTime() {
+        return remainingUnloadingTime;
+    }
+
+    /**
+     * @param remainingUnloadingTime the remainingUnloadingTime to set
+     */
+    public void setRemainingUnloadingTime(double remainingUnloadingTime) {
+        this.remainingUnloadingTime = remainingUnloadingTime;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/ShipArrivalProcess.java b/MV3302ClassCode/src/mv3302/ShipArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..e53c63941de1c83d5aa23925bc961ac7d9c58583
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/ShipArrivalProcess.java
@@ -0,0 +1,65 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package mv3302;
+
+import simkit.random.RandomVariate;
+
+/**
+ * The ShipArrivalProcess class extends the ArrivalProcess class and represents
+ * the arrival process for ships in a simulation. It generates ships at random
+ * intervals and assigns random unloading times to each ship.
+ *
+ * @author dansl
+ */
+public final class ShipArrivalProcess extends ArrivalProcess {
+
+    private RandomVariate interarrivalTimeGenerator;
+
+    private RandomVariate unloadingTimeGenerator;
+
+    /**
+     * Constructs a new ShipArrivalProcess with no generators set.
+     */
+    public ShipArrivalProcess() {
+    }
+
+    /**
+     * Constructs a new ShipArrivalProcess with the given generators for
+     * interarrival times and unloading times.
+     *
+     * @param interarrivalTimeGenerator the generator for interarrival times
+     * @param unloadingTimeGenerator the generator for unloading times
+     */
+    public ShipArrivalProcess(RandomVariate interarrivalTimeGenerator, RandomVariate unloadingTimeGenerator) {
+        super(interarrivalTimeGenerator);
+        setInterarrivalTimeGenerator(interarrivalTimeGenerator);
+        setUnloadingTimeGenerator(unloadingTimeGenerator);
+    }
+
+    /**
+     * Generates a new ship with a random unloading time and schedules its
+     * arrival in the simulation.
+     */
+    @Override
+    public void doArrival() {
+        super.doArrival();
+        Ship ship = new Ship(unloadingTimeGenerator.generate());
+        waitDelay("ShipArrival", 0.0, ship);
+    }
+
+    /**
+     * @return the unloadingTimeGenerator
+     */
+    public RandomVariate getUnloadingTimeGenerator() {
+        return unloadingTimeGenerator;
+    }
+
+    /**
+     * @param unloadingTimeGenerator the unloadingTimeGenerator to set
+     */
+    public void setUnloadingTimeGenerator(RandomVariate unloadingTimeGenerator) {
+        this.unloadingTimeGenerator = unloadingTimeGenerator;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/SimpleConstantRateMediator.java b/MV3302ClassCode/src/mv3302/SimpleConstantRateMediator.java
new file mode 100644
index 0000000000000000000000000000000000000000..d6bfb4e70161d51a4956d19333322e74617cbdec
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimpleConstantRateMediator.java
@@ -0,0 +1,90 @@
+package mv3302;
+
+import mv3302.sensor.SimpleConstantRateSensor;
+import simkit.SimEntityBase;
+import simkit.random.RandomVariate;
+import simkit.smd.Mover;
+
+/**
+ * The SimpleConstantRateMediator class represents a mediator that manages the
+ * interactions between a Mover object and a SimpleConstantRateSensor object. It
+ * extends the SimEntityBase class, which provides basic simulation entity
+ * functionality.
+ */
+public final class SimpleConstantRateMediator extends SimEntityBase {
+
+    /**
+     * Constructs a SimpleConstantRateMediator object with the specified
+     * exponential generator.
+     *
+     * @param exponentialGenerator the exponential generator to be used by the
+     * mediator
+     */
+    public SimpleConstantRateMediator(RandomVariate exponentialGenerator1) {
+        setExponentialGenerator(exponentialGenerator1);
+    }
+
+    protected RandomVariate exponentialGenerator;
+
+    /**
+     * Constructs a SimpleConstantRateMediator object with the specified
+     * exponential generator.
+     *
+     * @param exponentialGenerator the exponential generator to be used by the
+     * mediator
+     */
+    public void SimpleConstantRateMediator(RandomVariate exponentialGenerator) {
+        setExponentialGenerator(exponentialGenerator);
+    }
+
+    /**
+     * Performs the necessary actions when a Mover object enters the range of a
+     * SimpleConstantRateSensor object. If the target is not already detected by
+     * the sensor, it waits for a detection delay generated by the exponential
+     * generator.
+     *
+     * @param target the Mover object that entered the sensor's range
+     * @param sensor the SimpleConstantRateSensor object that detected the
+     * target
+     */
+    public void doEnterRange(Mover target, SimpleConstantRateSensor sensor) {
+        if (!sensor.getContacts().contains(target)) {
+            sensor.waitDelay("Detection", exponentialGenerator.generate(), target);
+        }
+    }
+
+    /**
+     * Performs the necessary actions when a Mover object exits the range of a
+     * SimpleConstantRateSensor object. If the target is not already undetected
+     * by the sensor, it waits for an undetection delay generated by the
+     * exponential generator.
+     *
+     * @param target the Mover object that exited the sensor's range
+     * @param sensor the SimpleConstantRateSensor object that lost contact with
+     * the target
+     */
+    public void doExitRange(Mover target, SimpleConstantRateSensor sensor) {
+        if (!sensor.getContacts().contains(target)) {
+            sensor.waitDelay("Undetection", exponentialGenerator.generate(), target);
+        }
+    }
+
+    /**
+     * Retrieves the exponential generator used by the mediator.
+     *
+     * @return the exponential generator used by the mediator
+     */
+    public RandomVariate getExponentialGenerator() {
+        return exponentialGenerator;
+    }
+
+    /**
+     * Sets the exponential generator for the mediator.
+     *
+     * @param exponentialGenerator the exponential generator to be set
+     */
+    public void setExponentialGenerator(RandomVariate exponentialGenerator) {
+        this.exponentialGenerator = exponentialGenerator;
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/SimpleConstantTimeMediator.java b/MV3302ClassCode/src/mv3302/SimpleConstantTimeMediator.java
new file mode 100644
index 0000000000000000000000000000000000000000..cfae58f305d0522f53e8d4f0dd4d157da3dcfb30
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimpleConstantTimeMediator.java
@@ -0,0 +1,41 @@
+package mv3302;
+
+import mv3302.sensor.SimpleConstantTimeSensor;
+import simkit.SimEntityBase;
+import simkit.smd.Mover;
+
+/**
+ * The SimpleConstantTimeMediator class represents a mediator between a target
+ * Mover object and a SimpleConstantTimeSensor object. It extends the
+ * SimEntityBase class, which provides basic simulation entity functionality.
+ */
+public class SimpleConstantTimeMediator extends SimEntityBase {
+
+    /**
+     * Performs the necessary actions when the target Mover enters the range of
+     * the sensor.
+     *
+     * @param target The Mover object that entered the range of the sensor.
+     * @param sensor The SimpleConstantTimeSensor object responsible for
+     * detecting the target.
+     */
+    public void doEnterRange(Mover target, SimpleConstantTimeSensor sensor) {
+        if (!sensor.getContacts().contains(target)) {
+            sensor.waitDelay("Detection", sensor.getTimeToDetect(), target);
+        }
+    }
+
+    /**
+     * Performs the necessary actions when the target Mover exits the range of
+     * the sensor.
+     *
+     * @param target The Mover object that exited the range of the sensor.
+     * @param sensor The SimpleConstantTimeSensor object responsible for
+     * detecting the target.
+     */
+    public void doExitRange(Mover target, SimpleConstantTimeSensor sensor) {
+        if (!sensor.getContacts().contains(target)) {
+            sensor.waitDelay("Undetection", 0.0, target);
+        }
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/SimpleCookieCutterMediator.java b/MV3302ClassCode/src/mv3302/SimpleCookieCutterMediator.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb04557f60df5a46e886077c666cd1fd150fbf42
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimpleCookieCutterMediator.java
@@ -0,0 +1,46 @@
+package mv3302;
+
+import mv3302.sensor.SimpleCookieCutterSensor;
+import simkit.SimEntityBase;
+import simkit.smd.Mover;
+
+/**
+ * The SimpleCookieCutterMediator class represents a mediator that interacts
+ * with a SimpleCookieCutterSensor to handle the detection and undetection of a
+ * Mover object. It extends the SimEntityBase class, which is a base class for
+ * simulation entities in SimKit.
+ */
+public class SimpleCookieCutterMediator extends SimEntityBase {
+
+    /**
+     * Handles the event when a Mover enters the range of the
+     * SimpleCookieCutterSensor. If the Mover is not already in the sensor's
+     * contacts, it waits for a "Detection" event to occur.
+     *
+     * @param target The Mover object that entered the sensor's range.
+     * @param sensor The SimpleCookieCutterSensor responsible for detection.
+     */
+    public void doEnterRange(Mover target, SimpleCookieCutterSensor sensor) {
+        if (!sensor.getContacts().contains(target)) {
+            sensor.waitDelay("Detection", 0.0, target);
+        }
+    }
+
+    /**
+     * Handles the event when a Mover exits the range of the
+     * SimpleCookieCutterSensor. If the Mover is not already in the sensor's
+     * contacts, it waits for an "Undetection" event to occur. If the Mover is
+     * still not detected, it interrupts the ongoing "Detection" event.
+     *
+     * @param target The Mover object that exited the sensor's range.
+     * @param sensor The SimpleCookieCutterSensor responsible for detection.
+     */
+    public void doExitRange(Mover target, SimpleCookieCutterSensor sensor) {
+        if (!sensor.getContacts().contains(target)) {
+            sensor.waitDelay("Undetection", 0.0, target);
+        }
+        if (!sensor.getContacts().contains(target)) {
+            interrupt("Detection", 0.0, target);
+        }
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/SimpleMover.java b/MV3302ClassCode/src/mv3302/SimpleMover.java
new file mode 100644
index 0000000000000000000000000000000000000000..29010a428ef8b6b0bdb9f6fba85d646aaa113bda
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimpleMover.java
@@ -0,0 +1,284 @@
+package mv3302;
+
+import java.awt.geom.Point2D;
+import static mv3302.SimplestMover.NaP;
+import simkit.Schedule;
+import simkit.SimEntityBase;
+
+import simkit.smd.Mover;
+
+/**
+ * A simple implementation of the DES "Mover" concept.
+ *
+ * @author ahbuss
+ */
+public class SimpleMover extends SimEntityBase implements Mover {
+
+    /**
+     * Start here
+     */
+    private Point2D initialLocation;
+
+    /**
+     * All movement will be at this speed
+     */
+    private double maxSpeed;
+
+    /**
+     * Current velocity vector
+     */
+    protected Point2D velocity;
+
+    /**
+     * Location where SimpleMover last stopped
+     */
+    protected Point2D lastStopLocation;
+
+    /**
+     * Current destination
+     */
+    protected Point2D destination;
+
+    /**
+     * simTime when move starts (or when it stops)
+     */
+    protected double startMoveTime;
+
+    /**
+     * Instantiate Point2D states by cloning NaP
+     */
+    public SimpleMover() {
+        lastStopLocation = (Point2D) NaP.clone();
+        velocity = (Point2D) NaP.clone();
+        destination = (Point2D) NaP.clone();
+    }
+
+    /**
+     * Instantiate with the given parameters
+     *
+     * @param initialLocation Given initial location
+     * @param maxSpeed Given maxSpeed
+     */
+    public SimpleMover(Point2D initialLocation, double maxSpeed) {
+        this();
+        setInitialLocation(initialLocation);
+        setMaxSpeed(maxSpeed);
+    }
+
+    /**
+     * set destination location to NaP<br>
+     * set lastStopLocation to initialLocation<br>
+     * set velocity to (0.0, 0.0)<br>
+     * set startMoveTime to 0.0
+     *
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        destination = (Point2D) NaP.clone();
+        lastStopLocation = getInitialLocation();
+        velocity.setLocation(0.0, 0.0);
+        startMoveTime = 0.0;
+    }
+
+    /**
+     * Nothing scheduled - waiting to hear MoveTo event
+     */
+    public void doRun() {
+        firePropertyChange("startMoveTime", getStartMoveTime());
+        firePropertyChange("lastStopLocation", getLastStopLocation());
+        firePropertyChange("velocity", getVelocity());
+        firePropertyChange("destination", getDestination());
+    }
+
+    /**
+     * To be "heard" from a mover manager.<br>
+     * set destination to the given argument<br>
+     * schedule StartMove if non-zero travel distance
+     *
+     * @param destination Given new destination
+     */
+    public void doMoveTo(Point2D destination) {
+        Point2D oldDestination = getDestination();
+        this.destination = destination;
+        firePropertyChange("destination", oldDestination, getDestination());
+
+        if (lastStopLocation.distance(destination) > 0.0) {
+            waitDelay("StartMove", 0.0, this);
+        }
+    }
+
+    /**
+     * set velocity per the new destination and maxSpeed<br>
+     * set startMoveTime to current simTime<br>
+     * schedule EndMove with delay of travel time
+     *
+     * @param mover Should be "this" Mover
+     */
+    @Override
+    public void doStartMove(Mover mover) {
+        Point2D oldVelocity = getVelocity();
+        velocity = new Point2D.Double(
+                destination.getX() - lastStopLocation.getX(),
+                destination.getY() - lastStopLocation.getY()
+        );
+
+        double distance = lastStopLocation.distance(destination);
+
+        velocity.setLocation(velocity.getX() * maxSpeed / distance,
+                velocity.getY() * maxSpeed / distance);
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
+        double oldStartMoveTime = getStartMoveTime();
+        startMoveTime = Schedule.getSimTime();
+        firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());
+
+        double travelTime = distance / maxSpeed;
+        waitDelay("EndMove", travelTime, mover);
+    }
+
+    /**
+     * Set lastStopLocation coordinates to destination<br>
+     * set velocity to (0.0, 0.0)<br>
+     * set destination of NaP
+     *
+     * @param mover Should be "this" Mover
+     */
+    public void doEndMove(Mover mover) {
+        Point2D oldLastStopLocation = getLastStopLocation();
+        lastStopLocation.setLocation(destination);
+        firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());
+
+        Point2D oldVelocity = getVelocity();
+        velocity.setLocation(0.0, 0.0);
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
+        Point2D oldDestination = getDestination();
+        destination.setLocation(NaP);
+        firePropertyChange("destination", oldDestination, getDestination());
+    }
+
+    /**
+     * Scheduled when Mover "stops" for a period of time.<br>
+     * Set lastStopLocation to currentLocation<br>
+     * setVelocity to (0.0, 0.0)
+     *
+     * @param mover Should be "this" Mover
+     */
+    @Override
+    public void doStop(Mover mover) {
+        Point2D oldLastStopLocation = getLastStopLocation();
+        lastStopLocation.setLocation(getCurrentLocation());
+        firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());
+
+        Point2D oldVelocity = getVelocity();
+        velocity.setLocation(0.0, 0.0);
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
+    }
+
+    /**
+     * to be "heard" from Mover Manager when stopping<br>
+     * Schedule Stop
+     */
+    public void doOrderStop() {
+        waitDelay("Stop", 0.0, this);
+    }
+
+    /**
+     * "Implicit" state - determined using the linear equation of motion.
+     *
+     * @return The current location of this Mover
+     */
+    @Override
+    public Point2D getCurrentLocation() {
+        Point2D currentLocation = (Point2D) NaP.clone();
+        double elapsedTime = Schedule.getSimTime() - getStartMoveTime();
+        currentLocation.setLocation(lastStopLocation.getX() + elapsedTime * velocity.getX(),
+                lastStopLocation.getY() + elapsedTime * velocity.getY());
+        return currentLocation;
+
+    }
+
+    /**
+     *
+     * @return the maxSpeed
+     */
+    @Override
+    public double getMaxSpeed() {
+        return this.maxSpeed;
+    }
+
+    /**
+     *
+     * @return copy of velocity
+     */
+    @Override
+    public Point2D getVelocity() {
+        return (Point2D) velocity.clone();
+    }
+
+    /**
+     * @return copy of the initialLocation
+     */
+    public Point2D getInitialLocation() {
+        return (Point2D) initialLocation;
+    }
+
+    /**
+     * @param initialLocation the initialLocation to set
+     */
+    public void setInitialLocation(Point2D initialLocation) {
+        this.initialLocation = (Point2D) initialLocation.clone();
+    }
+
+    /**
+     * @param maxSpeed the maxSpeed to set
+     * @throws IllegalArgumentException if maxSpeed &lt; 0.0
+     */
+    public void setMaxSpeed(double maxSpeed) {
+        if (maxSpeed < 0.0) {
+            throw new IllegalArgumentException("maxSpeed must be 0.0: " + maxSpeed);
+        }
+        this.maxSpeed = maxSpeed;
+    }
+
+    /**
+     * @return copy of the lastStopLocation
+     */
+    public Point2D getLastStopLocation() {
+        return (Point2D) lastStopLocation;
+    }
+
+    /**
+     * @return copy of the destination
+     */
+    public Point2D getDestination() {
+        return (Point2D) destination.clone();
+    }
+
+    /**
+     * @return the startMoveTime
+     */
+    public double getStartMoveTime() {
+        return startMoveTime;
+    }
+
+    /**
+     * 
+     * @return Name currentLocation velocity
+     */
+    @Override
+    public String toString() {
+        return String.format("%s %s %s", getName(), getCurrentLocation(), getVelocity());
+    }
+
+    /**
+     * 
+     * @return super toString()
+     */
+    public String paramString() {
+        return super.toString();
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..d971360051fb1a330452131bf8cd8ea638076660
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimplePathMoverManager.java
@@ -0,0 +1,170 @@
+package mv3302;
+
+import java.awt.geom.Point2D;
+import static mv3302.SimplestMover.NaP;
+import simkit.SimEntityBase;
+import simkit.smd.Mover;
+
+/**
+ * Simple Path Mover Manager. Directs a listening Mover to each wayPoint in
+ * order until the last, when it "stops"
+ *
+ * @author ahbuss
+ */
+public class SimplePathMoverManager extends SimEntityBase {
+
+    /**
+     * If true, start immediately
+     */
+    private boolean startOnRun;
+
+    /**
+     * Given list of wayPoints
+     */
+    private Point2D[] path;
+
+    /**
+     * index of next wayPoint
+     */
+    protected int nextIndex;
+
+    /**
+     * next destination
+     */
+    protected Point2D nextDestination;
+
+    /**
+     * Instantiate nextDestination as copy of NaP
+     */
+    public SimplePathMoverManager() {
+        nextDestination = (Point2D) NaP.clone();
+    }
+
+    /**
+     * Instantiate with the given parameters
+     *
+     * @param path Given path
+     * @param startOnRun if true, start on Run event
+     */
+    public SimplePathMoverManager(Point2D[] path, boolean startOnRun) {
+        this();
+        setPath(path);
+        setStartOnRun(startOnRun);
+    }
+
+    /**
+     * Set nextIndex to -1<br>
+     * set nextDestination to NaP coordinates
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        nextIndex = -1;
+        nextDestination.setLocation(NaP);
+    }
+
+    /**
+     * If startOnRun is true, schedule NextWayPoint
+     */
+    public void doRun() {
+        firePropertyChange("nextIndex", getNextIndex());
+
+        if (isStartOnRun()) {
+            waitDelay("NextWayPoint", 0.0);
+        }
+    }
+
+    /**
+     * Increment nextIndex<br>
+     * set nextDestination to path[nextIndex]<br>
+     * schedule MoveTo with nextDestination
+     */
+    public void doNextWayPoint() {
+        int oldNextIndex = getNextIndex();
+        nextIndex += 1;
+        firePropertyChange("nextIndex", oldNextIndex, getNextIndex());
+
+        Point2D oldDestination = getNextDestination();
+        nextDestination.setLocation(path[nextIndex]);
+        firePropertyChange("nextDestination", oldDestination, getNextDestination());
+
+        waitDelay("MoveTo", 0.0, getNextDestination());
+    }
+
+    /**
+     * If more way points on path, schedule NextWayPoint<br>
+     * Else schedule OrderStop
+     *
+     * @param mover Given Mover (should be the one this is listening to)
+     */
+    public void doEndMove(Mover mover) {
+        if (nextIndex < path.length - 1) {
+            waitDelay("NextWayPoint", 0.0);
+        }
+
+        if (nextIndex == path.length - 1) {
+            waitDelay("OrderStop", 0.0);
+        }
+    }
+
+    /**
+     * @return the startOnRun
+     */
+    public boolean isStartOnRun() {
+        return startOnRun;
+    }
+
+    /**
+     * @param startOnRun the startOnRun to set
+     */
+    public void setStartOnRun(boolean startOnRun) {
+        this.startOnRun = startOnRun;
+    }
+
+    /**
+     * @return topy of he path
+     */
+    public Point2D[] getPath() {
+        return path.clone();
+    }
+
+    /**
+     * 
+     * @param index Given index
+     * @return path[index]
+     */
+    public Point2D getPath(int index) {
+        return path[index];
+    }
+
+    /**
+     * @param path the path to set
+     */
+    public void setPath(Point2D[] path) {
+        this.path = path.clone();
+    }
+
+    /**
+     * 
+     * @param index Given index
+     * @param path Given waypoint
+     */
+    public void setPath(int index, Point2D path) {
+        this.path[index] = path;
+    }
+
+    /**
+     * @return the nextIndex
+     */
+    public int getNextIndex() {
+        return nextIndex;
+    }
+
+    /**
+     * @return copy of the nextDestination
+     */
+    public Point2D getNextDestination() {
+        return (Point2D) nextDestination.clone();
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..51a2b3ca5e90ef7388a1728ffd23464c996fec90
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimplePatrolMoverManager.java
@@ -0,0 +1,59 @@
+package mv3302;
+
+import java.awt.geom.Point2D;
+import simkit.smd.Mover;
+
+/**
+ * Similar to PathMoverManager; directs a Mover to a sequence of way points.
+ * Instead of stopping at the end, return to the first and cycle through again
+ * until stopped by an external component.
+ *
+ * @author dansl
+ */
+public class SimplePatrolMoverManager extends SimplePathMoverManager {
+
+    /**
+     * Zero argument constructor
+     */
+    public SimplePatrolMoverManager() {
+    }
+
+    /**
+     * Instantiate with the given parameters
+     *
+     * @param path Given path
+     * @param startOnRun if true, start on Run event
+     */
+    public SimplePatrolMoverManager(Point2D[] path, boolean startOnRun) {
+        super(path, startOnRun);
+    }
+
+    /**
+     * Always schedule NextWayPoint
+     *
+     * @param mover Given Mover
+     */
+    @Override
+    public void doEndMove(Mover mover) {
+        waitDelay("NextWaypoint", 0.0);
+
+    }
+
+    /**
+     * Increment nextIndext and set modulo the length of the path<br>
+     * setNextDestination<br>
+     * Schedule MoveTo
+     */
+    public void doNextWaypoint() {
+        int oldNextIndex = getNextIndex();
+        nextIndex = (nextIndex + 1) % getPath().length;
+        firePropertyChange("nextIndex", oldNextIndex, getNextIndex());
+
+        Point2D oldDestination = getNextDestination();
+        nextDestination.setLocation(getPath(nextIndex));
+        firePropertyChange("nextDestination", oldDestination, getNextDestination());
+
+        waitDelay("MoveTo", 0.0, getNextDestination());
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..b703beb2e369998d4262ae903d05903f4e66951d
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimpleRandomMoverManager.java
@@ -0,0 +1,134 @@
+package mv3302;
+
+import java.awt.geom.Point2D;
+import static mv3302.SimplestMover.NaP;
+import simkit.SimEntity;
+import simkit.SimEntityBase;
+import simkit.random.RandomVariate;
+
+/**
+ * A MoverManager that generates a random destination and directs a Mover there.
+ * When the Mover reaches that destination, generate the next, etc.
+ *
+ * @author ahbuss
+ */
+public class SimpleRandomMoverManager extends SimEntityBase {
+
+    /**
+     * Generates the coordinates
+     */
+    private RandomVariate[] coordinateGenerator;
+
+    /**
+     * If true, start on the Run event
+     */
+    private boolean startOnRun;
+
+    /**
+     * Next destination
+     */
+    protected Point2D nextWayPoint;
+
+    /**
+     * set nextWayPoint to clone of NaP
+     */
+    public SimpleRandomMoverManager() {
+        this.nextWayPoint = (Point2D) NaP.clone();
+    }
+
+    /**
+     *
+     * @param coordinateGenerator Given coordinate generators
+     * @param startOnRun if true, start in Run event
+     */
+    public SimpleRandomMoverManager(RandomVariate[] coordinateGenerator, boolean startOnRun) {
+        this();
+        this.setCoordinateGenerator(coordinateGenerator);
+        this.setStartOnRun(startOnRun);
+    }
+
+    /**
+     * set nextWayPoint to NaP coordinates
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        nextWayPoint.setLocation(NaP);
+    }
+
+    /**
+     * If startOnRun, schedule Start event
+     */
+    public void doRun() {
+        firePropertyChange("nextWayPoint", getNextWayPoint());
+        if (isStartOnRun()) {
+            waitDelay("Start", 0.0);
+        }
+    }
+
+    /**
+     * Generate nextWaypoint<br>
+     * schedule MoveTo
+     */
+    public void doStart() {
+        nextWayPoint = new Point2D.Double(coordinateGenerator[0].generate(), coordinateGenerator[1].generate());
+        firePropertyChange("nextWaypoint", getNextWayPoint());
+
+        waitDelay("MoveTo", 0.0, nextWayPoint);
+    }
+
+    /**
+     * To be "heard" from Mover. generate nextWayPoint and schedule MoveTo
+     *
+     * @param mover Given Mover
+     */
+    public void doEndMove(SimEntity mover) {
+        nextWayPoint = new Point2D.Double(coordinateGenerator[0].generate(), coordinateGenerator[1].generate());
+        firePropertyChange("nextWaypoint", getNextWayPoint());
+
+        waitDelay("MoveTo", 0.0, nextWayPoint);
+    }
+
+    /**
+     * Schedule OrderStop (which should "Stop" the Mover listening)
+     */
+    public void doStop() {
+        waitDelay("OrderStop", 0.0);
+    }
+
+    /**
+     * @return copy of the coordinateGenerator
+     */
+    public RandomVariate[] getCoordinateGenerator() {
+        return coordinateGenerator.clone();
+    }
+
+    /**
+     * @param coordinateGenerator the coordinateGenerator to set (copy of)
+     */
+    public void setCoordinateGenerator(RandomVariate[] coordinateGenerator) {
+        this.coordinateGenerator = coordinateGenerator.clone();
+    }
+
+    /**
+     * @return the startOnRun
+     */
+    public boolean isStartOnRun() {
+        return startOnRun;
+    }
+
+    /**
+     * @param startOnRun the startOnRun to set
+     */
+    public void setStartOnRun(boolean startOnRun) {
+        this.startOnRun = startOnRun;
+    }
+
+    /**
+     * @return the nextWayPoint
+     */
+    public Point2D getNextWayPoint() {
+        return nextWayPoint;
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/SimpleReferee.java b/MV3302ClassCode/src/mv3302/SimpleReferee.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc5ee20125c9de09a19fe80366feb6eb933e7f26
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimpleReferee.java
@@ -0,0 +1,300 @@
+package mv3302;
+
+import java.awt.geom.Point2D;
+import static java.lang.Math.sqrt;
+import java.util.ArrayList;
+import java.util.List;
+import simkit.SimEntityBase;
+import static simkit.smd.Math2D.ZERO;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+/**
+The SimpleReferee class represents a referee in a simulation. It extends the SimEntityBase class,
+which provides basic functionality for simulation entities.
+*/
+public final class SimpleReferee extends SimEntityBase {
+
+    private List<Sensor> sensors;
+
+    private List<Mover> targets;
+
+    /**
+Constructs a SimpleReferee object with an empty list of sensors and targets.
+*/
+    
+    public SimpleReferee() {
+    }
+
+    /**
+Constructs a SimpleReferee object with the specified lists of sensors and targets.
+@param sensors the list of sensors to set
+@param targets the list of targets to set
+*/
+    
+    public SimpleReferee(List<Sensor> sensors, List<Mover> targets) {
+        setSensors(sensors);
+        setTargets(targets);
+    }
+
+    /**
+Performs the run logic for the referee. If there are sensors present, it waits for the "InitSensor"
+event with zero delay.
+*/
+    
+    public void doRun() {
+        if (!sensors.isEmpty()) {
+            waitDelay("InitSensor", 0.0, 0);
+        }
+    }
+
+    /**
+Initializes a sensor at the specified index. Adds the sensor as a simulation event listener.
+If there are more sensors to initialize, it waits for the "InitSensor" event for the next index.
+@param i the index of the sensor to initialize
+*/
+    
+    public void doInitSensor(int i) {
+        sensors.get(i).addSimEventListener(this);
+
+        if (i < sensors.size() - 1) {
+            waitDelay("InitSensor", 0.0, i + 1);
+        }
+
+        waitDelay("InitTarget", 0.0, i, 0);
+    }
+
+    /**
+Initializes a target at the specified indices. Adds the target as a simulation event listener.
+If there are more targets to initialize, it waits for the "InitTarget" event for the next indices.
+Checks if the target is within range of the sensor and waits for the "EnterRange" event if necessary.
+@param i the index of the sensor
+@param j the index of the target
+*/
+    
+    public void doInitTarget(int i, int j) {
+        targets.get(j).addSimEventListener(this);
+        if (j < targets.size() - 1) {
+            waitDelay("InitTarget", 0.0, i, j + 1);
+        }
+
+        if (targets.get(j).getCurrentLocation().distance(sensors.get(i).getCurrentLocation()) < sensors.get(i).getMaxRange()) {
+            if (!targets.get(j).equals(sensors.get(i).getMover())) {
+                waitDelay("EnterRange", 0.0, targets.get(j), sensors.get(i));
+            }
+        }
+    }
+  
+    /**
+Updates a sensor with a target. Checks if the sensor and target are different and calculates
+the enter and exit times. Handles different cases based on the number of times calculated.
+If there are more sensors to update, it waits for the "UpdateSensor" event for the next index.
+@param i the index of the sensor
+@param target the target to update the sensor with
+*/
+    
+    public void doUpdateSensor(int i, Mover target) {
+        Sensor sensor = sensors.get(i);
+        if (!sensor.equals(target)) {
+            double[] times = getEnterExitTimes(target, sensor);
+            switch (times.length) {
+                case 0 -> {
+                }
+                case 1 -> {
+                    interrupt("ExitRange", target, sensor);
+                    waitDelay("ExitRange", times[0], target, sensor);
+                }
+                case 2 -> {
+                    interrupt("EnterRange", target, sensor);
+                    waitDelay("EnterRange", times[0], target, sensor);
+                }
+            }
+        }
+
+        if (i < sensors.size() - 1) {
+            waitDelay("UpdateSensor", 0.0, i + 1, target);
+        }
+    }
+    
+    /**
+ * Notifies the referee that a target is starting to move. Initiates the "UpdateSensor" event
+ * with zero delay for the specified target.
+ *
+ * @param target the target that is starting to move
+ */
+    
+    public void doStartMove(Mover target) {
+        waitDelay("UpdateSensor", 0.0, 0, target);
+    }
+
+   /**
+ * Notifies the referee that a target has stopped. Initiates the "UpdateSensor" event
+ * with zero delay for the specified target.
+ *
+ * @param target the target that has stopped
+ */ 
+    
+    public void doStop(Mover target) {
+        waitDelay("UpdateSensor", 0.0, 0, target);
+    }
+
+    /**
+ * Updates a target with a sensor. Checks if the target and sensor are different and calculates
+ * the enter and exit times. Handles different cases based on the number of times calculated.
+ * If there are more targets to update, it waits for the "UpdateTarget" event for the next index.
+ *
+ * @param i      the index of the target
+ * @param sensor the sensor to update the target with
+ */
+    
+    public void doUpdateTarget(int i, Sensor sensor) {
+        Mover target = targets.get(i);
+        double[] times = getEnterExitTimes(target, sensor);
+        switch (times.length) {
+            case 0 -> {
+            }
+            case 1 -> {
+                interrupt("ExitRange", target, sensor);
+                waitDelay("ExitRange", times[0], target, sensor);
+            }
+            case 2 -> {
+                interrupt("EnterRange", target, sensor);
+                waitDelay("EnterRange", times[0], target, sensor);
+            }
+        }
+        
+        if (i < targets.size() - 1) {
+            waitDelay("UpdateTarget", i + 1, sensor);
+        }
+    }
+
+    /**
+ * Notifies the referee that a sensor is starting to move. Initiates the "UpdateTarget" event
+ * with zero delay for the specified sensor.
+ *
+ * @param sensor the sensor that is starting to move
+ */
+    
+    public void doStartMove(Sensor sensor) {
+        waitDelay("UpdateTarget", 0.0, 0, sensor);
+    }
+
+    /**
+ * Notifies the referee that a sensor has stopped. Initiates the "UpdateTarget" event
+ * with zero delay for the specified sensor.
+ *
+ * @param sensor the sensor that has stopped
+ */
+    
+    public void doStop(Sensor sensor) {
+        waitDelay("UpdateTarget", 0.0, 0, sensor);
+    }
+    
+    /**
+ * Performs the actions when a target enters the range of a sensor. Calculates the enter and exit times
+ * and waits for the "ExitRange" event if necessary.
+ *
+ * @param target the target that entered the range
+ * @param sensor the sensor that detected the target
+ */
+
+    public void doEnterRange(Mover target, Sensor sensor) {
+        double[] times = getEnterExitTimes(target, sensor);
+        if (times.length == 1) {
+            waitDelay("ExitRange", times[0], target, sensor);
+        } else if (times.length == 2) {
+            waitDelay("ExitRange", times[1], target, sensor);
+        }
+    }
+    
+    /**
+ * Performs the actions when a target exits the range of a sensor.
+ *
+ * @param target the target that exited the range
+ * @param sensor the sensor that lost track of the target
+ */
+    
+    public void doExitRange(Mover target, Sensor sensor) {
+    }
+
+    /**
+ * Calculates the enter and exit times for a target and a sensor based on their relative locations
+ * and velocities. Returns an array of the calculated times.
+ *
+ * @param target the target to calculate times for
+ * @param sensor the sensor to calculate times for
+ * @return an array of the enter and exit times, or an empty array if no times were calculated
+ */
+    
+    private double[] getEnterExitTimes(Mover target, Sensor sensor) {
+        double[] times;
+
+        Point2D relativeLocation = new Point2D.Double(
+                target.getCurrentLocation().getX() - sensor.getCurrentLocation().getX(),
+                target.getCurrentLocation().getY() - sensor.getCurrentLocation().getY()
+        );
+        Point2D relativeVelocity = new Point2D.Double(
+                target.getVelocity().getX() - sensor.getVelocity().getX(),
+                target.getVelocity().getY() - sensor.getVelocity().getY()
+        );
+
+        double velocitySquared = relativeVelocity.distanceSq(ZERO);
+        double distanceSqured = relativeLocation.distanceSq(ZERO);
+
+        double innerProduct = relativeLocation.getX() * relativeVelocity.getX()
+                + relativeLocation.getY() * relativeVelocity.getY();
+
+        double determinant = velocitySquared * (sensor.getMaxRange() * sensor.getMaxRange()
+                - distanceSqured) + innerProduct * innerProduct;
+        if (determinant < 0.0) {
+            times = new double[0];
+        } else {
+            double first = -innerProduct / velocitySquared;
+            double smallerRoot = first - sqrt(determinant) / velocitySquared;
+            double biggerRoot = first + sqrt(determinant) / velocitySquared;
+            if (smallerRoot > 0.0) {
+                times = new double[]{smallerRoot, biggerRoot};
+            } else if (biggerRoot > 0) {
+                times = new double[]{biggerRoot};
+            } else {
+                times = new double[0];
+            }
+        }
+
+        return times;
+    }
+
+/**
+ * Returns a new list containing the sensors in the simulation.
+ * @return a list of sensors
+ */
+    public List<Sensor> getSensors() {
+        return new ArrayList<>(sensors);
+    }
+
+/**
+ * Sets the list of sensors for the simulation.
+ *
+ * @param sensors the list of sensors to set
+ */
+    public void setSensors(List<Sensor> sensors) {
+        this.sensors = new ArrayList<>(sensors);
+    }
+
+/**
+ * Returns a new list containing the targets in the simulation.
+ *
+ * @return a list of targets
+ */
+    public List<Mover> getTargets() {
+        return new ArrayList<>(targets);
+    }
+
+/**
+ * Sets the list of targets for the simulation.
+ *
+ * @param targets the list of targets to set
+ */
+    public void setTargets(List<Mover> targets) {
+        this.targets = new ArrayList<>(targets);
+    }
+}
\ No newline at end of file
diff --git a/MV3302ClassCode/src/mv3302/SimpleServer.java b/MV3302ClassCode/src/mv3302/SimpleServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..318b1a4e348aa1ee751f4e056877d83dbeeb285e
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimpleServer.java
@@ -0,0 +1,170 @@
+package mv3302;
+
+import simkit.Priority;
+import simkit.SimEntityBase;
+import simkit.random.RandomVariate;
+
+/**
+ * Class that simulates a simple server by extending SimEntityBase
+ *
+ * @author dansl
+ */
+public class SimpleServer extends SimEntityBase {
+
+    // Instance variables to hold the changing states during the simulation
+    protected int numberInQueue;
+    protected int numberAvailableServers;
+    protected int numberServed;
+    // Instance variables that hold the build settings of the simulation
+    private int totalNumberServers;
+    private RandomVariate serviceTimeGenerator;
+
+    /**
+     * Constructor method for the SimpleServer class; initializes the number of
+     * servers and service times for the simulation
+     *
+     * @param numberServers
+     * @param serviceTime
+     */
+    public SimpleServer(int numberServers, RandomVariate serviceTime) {
+        totalNumberServers = numberServers;
+        serviceTimeGenerator = serviceTime;
+    }
+
+    /**
+     * Getter method for number of customers in the queue
+     *
+     * @return the numberInQueue
+     */
+    public int getNumberInQueue() {
+        return numberInQueue;
+    }
+
+    /**
+     * Getter method for the number of servers available in the simulation
+     *
+     * @return the numberAvailableServers
+     */
+    public int getNumberAvailableServers() {
+        return numberAvailableServers;
+    }
+
+    /**
+     * Getter method returns the total number of customers complete through the
+     * processing process
+     *
+     * @return the numberServed
+     */
+    public int getNumberServed() {
+        return numberServed;
+    }
+
+    /**
+     * Getter method that returns the total number of servers in the simulation
+     *
+     * @return the totalNumberServers
+     */
+    public int getTotalNumberServers() {
+        return totalNumberServers;
+    }
+
+    /**
+     * Setter method sets the total number of servers the simulation will use
+     *
+     * @param totalNumberServers
+     * @throws IllegalArgumentException if totalNumberServers <= 0 @ param
+     * totalNumberServers the totalNumberServers
+     */
+    public void setTotalNumberServers(int totalNumberServers) {
+        if (totalNumberServers <= 0) {
+            throw new IllegalArgumentException("totalNumberServers must be > 0: "
+                    + totalNumberServers);
+        }
+        this.totalNumberServers = totalNumberServers;
+    }
+
+    /**
+     * Getter method that returns a service time value
+     *
+     * @return the serviceTimeGenerator
+     */
+    public RandomVariate getServiceTimeGenerator() {
+        return serviceTimeGenerator;
+    }
+
+    /**
+     * setter method that sets a service time value
+     *
+     * @param serviceTimeGenerator the serviceTimeGenerator to set
+     */
+    public void setServiceTimeGenerator(RandomVariate serviceTimeGenerator) {
+        this.serviceTimeGenerator = serviceTimeGenerator;
+    }
+
+    /**
+     * Reset method that returns the simulation to it's original state
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        numberInQueue = 0;
+        numberAvailableServers = totalNumberServers;
+        numberServed = 0;
+    }
+
+    /**
+     * Run method fires the state changes to update the listeners
+     */
+    public void doRun() {
+        firePropertyChange("numberInQueue", getNumberInQueue());
+        firePropertyChange("numberAvailableServers", getNumberAvailableServers());
+        firePropertyChange("numberServed", getNumberServed());
+    }
+
+    /**
+     * Creates an arrival event, alters the total number of arrivals and
+     * schedules the next event
+     */
+    public void doArrival() {
+        int oldNumberInQueue = getNumberInQueue();
+        numberInQueue = numberInQueue + 1;
+        firePropertyChange("numberInQueue", oldNumberInQueue, getNumberInQueue());
+
+        if (getNumberAvailableServers() > 0) {
+            waitDelay("StartService", 0.0, Priority.HIGH);
+        }
+    }
+
+    /**
+     * Method decreases the number of customers waiting in the queue and the
+     * number of available servers. Method then fires those changes for the
+     * listeners then schedules the EndService
+     */
+    public void doStartService() {
+        int oldNumberInQueue = getNumberInQueue();
+        int oldNumberAvailableServers = getNumberAvailableServers();
+        numberAvailableServers = numberAvailableServers - 1;
+        numberInQueue = numberInQueue - 1;
+        firePropertyChange("numberInQueue", oldNumberInQueue, getNumberInQueue());
+        firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
+        waitDelay("EndService", getServiceTimeGenerator());
+    }
+
+    /**
+     * Method increases the number of customers that have been served and the
+     * number of available servers. Method then fires those changes for the
+     * listeners and schedules the StartService as long as the queue is greater
+     * than one.
+     */
+    public void doEndService() {
+        int oldNumberAvailableServers = getNumberAvailableServers();
+        numberAvailableServers = numberAvailableServers + 1;
+        int oldNumberServed = getNumberServed();
+        numberServed = numberServed + 1;
+        firePropertyChange("numberAvailableServers", oldNumberAvailableServers, getNumberAvailableServers());
+        firePropertyChange("numberServed", oldNumberServed, getNumberServed());
+        if (getNumberInQueue() > 0) {
+            waitDelay("StartService", 0.0, Priority.HIGH);
+        }
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/SimplestMover.java b/MV3302ClassCode/src/mv3302/SimplestMover.java
new file mode 100644
index 0000000000000000000000000000000000000000..f24607b670bbc41a915b912b6c77effa795b6fb7
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/SimplestMover.java
@@ -0,0 +1,170 @@
+package mv3302;
+
+import java.awt.geom.Point2D;
+import static java.lang.Double.NaN;
+import simkit.Schedule;
+import simkit.SimEntityBase;
+
+/**
+ *
+ * @author ahbuss
+ */
+public class SimplestMover extends SimEntityBase {
+
+    public static final Point2D NaP = new Point2D.Double(NaN, NaN);
+
+    private Point2D initialLocation;
+
+    private double maxSpeed;
+
+    protected Point2D lastStopLocation;
+
+    protected Point2D velocity;
+
+    protected Point2D destination;
+
+    protected double startMoveTime;
+
+    public SimplestMover() {
+        lastStopLocation = (Point2D) NaP.clone();
+        velocity = (Point2D) NaP.clone();
+        destination = (Point2D) NaP.clone();
+    }
+
+    public SimplestMover(Point2D initialLocation, double maxSpeed) {
+        this();
+        setInitialLocation(initialLocation);
+        setMaxSpeed(maxSpeed);
+    }
+
+    @Override
+    public void reset() {
+        super.reset();
+        lastStopLocation.setLocation(initialLocation);
+        velocity.setLocation(0.0, 0.0);
+        destination.setLocation(NaP);
+        startMoveTime = 0.0;
+    }
+
+    public void doRun() {
+        firePropertyChange("lastStopLocation", getLastStopLocation());
+        firePropertyChange("velocity", getVelocity());
+        firePropertyChange("destination", getDestination());
+        firePropertyChange("startMoveTime", getStartMoveTime());
+    }
+
+    public void doMoveTo(Point2D newDestination) {
+        Point2D oldDestination = getDestination();
+        this.destination.setLocation(newDestination);
+        firePropertyChange("destination", oldDestination, getDestination());
+
+        if (lastStopLocation.distance(destination) > 0.0) {
+            waitDelay("StartMove", 0.0);
+        }
+    }
+
+    public void doStartMove() {
+        double oldStartMoveTime = getStartMoveTime();
+        startMoveTime = Schedule.getSimTime();
+        firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());
+
+        double distance = lastStopLocation.distance(destination);
+        double a = getMaxSpeed() / distance;
+
+        Point2D oldVelocity = getVelocity();
+        velocity.setLocation(destination.getX() - lastStopLocation.getX(), destination.getY() - lastStopLocation.getY());
+        velocity.setLocation(a * velocity.getX(), a * velocity.getY());
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
+        waitDelay("EndMove", 1.0 / a);
+    }
+
+    public void doEndMove() {
+        double oldStartMoveTime = getStartMoveTime();
+        startMoveTime = Schedule.getSimTime();
+        firePropertyChange("startMoveTime", oldStartMoveTime, getStartMoveTime());
+
+        Point2D oldLastStopLocation = getLastStopLocation();
+        lastStopLocation.setLocation(destination);
+        firePropertyChange("lastStopLocation", oldLastStopLocation, getLastStopLocation());
+
+        Point2D oldVelocity = getVelocity();
+        velocity.setLocation(0.0, 0.0);
+        firePropertyChange("velocity", oldVelocity, getVelocity());
+
+    }
+
+    /**
+     * @return the initialLocation
+     */
+    public Point2D getInitialLocation() {
+        return (Point2D) initialLocation.clone();
+    }
+
+    /**
+     * @param initialLocation the initialLocation to set
+     */
+    public void setInitialLocation(Point2D initialLocation) {
+        this.initialLocation = (Point2D) initialLocation.clone();
+    }
+
+    /**
+     * @return the maxSpeed
+     */
+    public double getMaxSpeed() {
+        return maxSpeed;
+    }
+
+    /**
+     * @param maxSpeed the maxSpeed to set
+     */
+    public void setMaxSpeed(double maxSpeed) {
+        if (maxSpeed < 0.0) {
+            throw new IllegalArgumentException("maxSpeed must be >= 0.0: " + maxSpeed);
+        }
+        this.maxSpeed = maxSpeed;
+    }
+
+    /**
+     * @return the lastStopLocation
+     */
+    public Point2D getLastStopLocation() {
+        return (Point2D) lastStopLocation.clone();
+    }
+
+    /**
+     * @return the velocity
+     */
+    public Point2D getVelocity() {
+        return (Point2D) velocity.clone();
+    }
+
+    /**
+     * @return the destination
+     */
+    public Point2D getDestination() {
+        return (Point2D) destination.clone();
+    }
+
+    /**
+     * @return the startMoveTime
+     */
+    public double getStartMoveTime() {
+        return startMoveTime;
+    }
+
+    public Point2D getCurrentLocation() {
+        double elapsedTime = Schedule.getSimTime() - getStartMoveTime();
+        return new Point2D.Double(lastStopLocation.getX() + elapsedTime * velocity.getX() , 
+            lastStopLocation.getY() + elapsedTime * velocity.getY());
+    }
+    
+    @Override
+    public String toString() {
+        return String.format("%s %s", getName(), getCurrentLocation());
+    }
+    
+    public String paramString() {
+        return super.toString();
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/StoppedPartArrivalProcess.java b/MV3302ClassCode/src/mv3302/StoppedPartArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..5daa5d407c6ee1397975fa899df67e69d815b2a5
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/StoppedPartArrivalProcess.java
@@ -0,0 +1,63 @@
+package mv3302;
+
+/**
+ * The StoppedPartArrivalProcess class extends the PartArrivalProcess class and
+ * represents a process that stops the arrival of parts for a specified
+ * duration. It overrides the doRun() method to wait for a specified stop time
+ * before resuming the arrival of parts. It also provides methods to schedule
+ * the next arrival and get/set the stop time.
+ *
+ * @author dansl
+ */
+public final class StoppedPartArrivalProcess extends PartArrivalProcess {
+
+    private int stopTime;
+
+    /**
+     * Zero-argument constructor
+     */
+    public StoppedPartArrivalProcess() {
+        super();
+    }
+
+    /**
+     * Constructs a StoppedPartArrivalProcess object with the given stop time.
+     *
+     * @param stopTime The duration for which the arrival of parts should be
+     * stopped.
+     */
+    public StoppedPartArrivalProcess(int stopTime) {
+        this.stopTime = stopTime;
+    }
+
+    /**
+     * Overrides the doRun() method from the parent class. Pauses the arrival of
+     * parts for the specified stop time.
+     */
+    @Override
+    public void doRun() {
+        waitDelay("StopArrivals", getStopTime());
+    }
+
+    /**
+     * Schedule the next arrival after stopping. This method schedules the
+     * Arrival(index) process.
+     */
+    public void doStopArrivals() {
+        interrupt("Arrival");
+    }
+
+    /**
+     * @return the stopTime
+     */
+    public int getStopTime() {
+        return stopTime;
+    }
+
+    /**
+     * @param stopTime the stopTime to set
+     */
+    public void setStopTime(int stopTime) {
+        this.stopTime = stopTime;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/TransferLineComponent.java b/MV3302ClassCode/src/mv3302/TransferLineComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..8086aa8b4d265436e46e1dc0777fb12032f93920
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/TransferLineComponent.java
@@ -0,0 +1,331 @@
+package mv3302;
+
+import simkit.*;
+import java.util.*;
+import simkit.random.RandomVariate;
+
+public class TransferLineComponent extends SimEntityBase {
+
+    private int[] totalNumberMachines;
+    private RandomVariate[] processingTimeGenerator;
+    protected int[] numberAvailableMachines;
+    protected List<SortedSet<Part>> queue;
+    protected double[] delayInQueue;
+    protected double[] timeAtStation;
+    protected double totalDelayInQueue;
+    protected double totalTimeInSystem;
+    protected int numberComplete;
+
+    /**
+     * Constructor method for TransferLineComponent that passes in Array values
+     * of processingTimeGenerator and totalNumberMachines as sets them
+     * accordingly. Sets the values of numberAvailableMachines to
+     * totalNumberMachines. Sets the length of the delayInQueue and
+     * timeAtStation arrays to the length of totalNumberMachines. Instantiates
+     * the value of the queue to an empty array with elements as treesets the
+     * length of elements in totalNumberMachines
+     *
+     * @param processingTimeGenerator
+     * @param totalNumberMachines
+     */
+    public TransferLineComponent(RandomVariate[] processingTimeGenerator, int[] totalNumberMachines) {
+
+        this();
+        this.setProcessingTimeGenerator(processingTimeGenerator);
+        this.setTotalNumberMachines(totalNumberMachines);
+        numberAvailableMachines = totalNumberMachines.clone();
+        delayInQueue = new double[totalNumberMachines.length];
+        timeAtStation = new double[totalNumberMachines.length];
+        queue = new ArrayList<>();
+        for (int station = 0; station < totalNumberMachines.length; ++station) {
+            queue.add(new TreeSet<>());
+        }
+    }
+
+    /**
+     * Zero Argument constructor method that makes a call to it's super.
+     *
+     */
+    public TransferLineComponent() {
+        super();
+
+    }
+
+    /**
+     * Reset method resets all values to their base before the start of the next
+     * machine run. resets the numberOfAvailable machines back to the same
+     * property as the totalNumberMachines. Also resets the values contained
+     * within the delayInQueue and timeAtStation array back to the default NaN
+     * value. Clears the contents of the queue.
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        numberAvailableMachines = getTotalNumberMachines().clone();
+        Arrays.fill(delayInQueue, Double.NaN);
+        Arrays.fill(timeAtStation, Double.NaN);
+
+    }
+
+    /**
+     * Do run method instantiates the total delay in queue and time in system
+     * variables to NaN value. Fires Property changes for total delay in queue,
+     * total delay in system and number of available machines. Schedules next
+     * Init Event.
+     */
+    public void doRun() {
+        totalDelayInQueue = Double.NaN;
+        totalTimeInSystem = Double.NaN;
+//        firePropertyChange("totalDelayInQueue", getTotalDelayInQueue());
+//        firePropertyChange("totalDelayInSystem", getTotalTimeInSystem());
+//        firePropertyChange("numberAvailableMachines", getNumberAvailableMachines());
+        waitDelay("Init", 0.0, 0);
+    }
+
+    /**
+     * Init method starts with 0 as the parameter and aligns the indexes for the
+     * number available machines to the indexes of totalNumberMachines.Fires the
+     * necessary index property changes. Calls the queue array for the element
+     * at index i and clears that element. It then sets the values of the
+     * delayInQueue and timeAtStation array elements back to NaN. It then
+     * schedules another Init event as long as the i argument is less than the
+     * totalNumberOfMachines length minus one to account for the off by one 0
+     * index.
+     *
+     * @param i
+     */
+    public void doInit(int i) {
+        this.numberAvailableMachines[i] = totalNumberMachines[i];
+//            fireIndexedPropertyChange(i, "numberAvailableMachines", getNumberAvailableMachines(i));
+        queue.get(i).clear();
+//            fireIndexedPropertyChange(i, "queue", getQueue(i));
+//            double[] oldDelayInQueue = getDelayInQueue().clone();
+        delayInQueue[i] = Double.NaN;
+//            firePropertyChange("delayInQueue", oldDelayInQueue, getDelayInQueue());
+//            double[] oldTimeAtStation = getTimeAtStation().clone();
+        timeAtStation[i] = Double.NaN;
+//            firePropertyChange("timeAtStation", oldTimeAtStation, getTimeAtStation());
+        if (i < totalNumberMachines.length - 1) {
+            waitDelay("Init", 0.0, i + 1);
+        }
+    }
+
+    /**
+     * doArrival() method takes in arguments Part Part, and int station.The
+     * method takes a time stamp on the part, Method then takes the queue at the
+     * station i and adds the part value to it. Fires changes to the listener
+     * then schedules the startProcessing event if numberAvailableMachines is
+     * greater than 0.
+     *
+     * @param part
+     * @param station
+     */
+    public void doArrival(Part part, int station) {
+        part.stampTime();
+        SortedSet<Part> oldQueue = getQueue(station);
+        queue.get(station).add(part);
+        fireIndexedPropertyChange(station, "queue", oldQueue, getQueue(station));
+        if (numberAvailableMachines[station] > 0) {
+            waitDelay("StartProcessing", 0.0, station);
+        }
+    }
+
+    /**
+     * doStartProcessing method takes the part at station and removes it from
+     * the queue, The number of available machines at station are reduced by
+     * one. the delay in queue array value at station is set to the part elapsed
+     * time. The part delay in queue is then incremented
+     *
+     * @param station
+     */
+    public void doStartProcessing(int station) {
+        SortedSet<Part> oldQueue = queue.get(station);
+        Part part = oldQueue.first();
+
+        queue.get(station).remove(part);
+//fireIndexedPropertyChange(station, "queue", oldQueue, getQueue(station));
+        int[] oldNumberAvailableMachines = getNumberAvailableMachines().clone();
+        numberAvailableMachines[station]--;
+        fireIndexedPropertyChange(station, "numberAvailableMachines", oldNumberAvailableMachines[station], getNumberAvailableMachines()[station]);
+        double[] oldDelayInQueue = getDelayInQueue();
+        delayInQueue[station] = part.getElapsedTime();
+
+        fireIndexedPropertyChange(station, "delayInQueue", oldDelayInQueue[station], delayInQueue[station]);
+        part.incrementDelayInQueue(delayInQueue[station]);
+
+        waitDelay("EndProcessing", getProcessingTimeGenerator()[station].generate(), part, station);
+    }
+
+    /**
+     * doEndProcessing() method takes in arguments for part and i. Takes
+     * numberAvailableMachines at element i and increases it by one. Also
+     * assigns timeAtStation to the elapsed time variable of the current part.
+     * Finally determines the path for scheduling based on the preferred
+     * conditions.
+     */
+    public void doEndProcessing(Part part, int station) {
+        int[] oldNumberAvailableMachines = getNumberAvailableMachines().clone();
+        numberAvailableMachines[station]++;
+        fireIndexedPropertyChange(station, "numberAvailableMachines", oldNumberAvailableMachines[station], getNumberAvailableMachines()[station]);
+        double[] oldTimeAtStation = getTimeAtStation().clone();
+        timeAtStation[station] = part.getElapsedTime();
+        fireIndexedPropertyChange(station, "timeAtStation", oldTimeAtStation[station], getTimeAtStation(station));
+        if (station < totalNumberMachines.length - 1) {
+            waitDelay("Arrival", 0.0, part, station + 1);
+        }
+        if (station == totalNumberMachines.length - 1) {
+            waitDelay("PartComplete", 0.0, part);
+        }
+        if (!queue.get(station).isEmpty()) {
+            waitDelay("StartProcessing", 0.0, station);
+        }
+    }
+
+    /**
+     * doPartComplete brings in argument part and assigns the value of
+     * totalTimeInSystem to the parts getAge() value. It also assigns the
+     * totalDelayInQueue variable to the part's totalDelay(). Increments the
+     * number of completed parts by one.
+     */
+    public void doPartComplete(Part part) {
+        double oldTotalTimeInSystem = totalTimeInSystem;
+        totalTimeInSystem = part.getAge();
+        firePropertyChange("totalTimeInSystem", oldTotalTimeInSystem, getTotalTimeInSystem());
+        double oldTotalDelayInQueue = totalDelayInQueue;
+        totalDelayInQueue = part.getTotalDelayInQueue();
+        firePropertyChange("totalDelayInQueue", oldTotalDelayInQueue, getTotalDelayInQueue());
+    }
+
+    /**
+     * @return the totalNumberMachines
+     */
+    public int[] getTotalNumberMachines() {
+        return totalNumberMachines.clone();
+    }
+
+    /**
+     * @param station
+     * @return the totalNumberMachines @ station
+     */
+    public int getTotalNumberMachines(int station) {
+        return totalNumberMachines[station];
+    }
+
+    /**
+     * @return the processingTimeGenerator
+     */
+    public RandomVariate[] getProcessingTimeGenerator() {
+        return processingTimeGenerator.clone();
+    }
+
+    /**
+     * @return the processingTimeGenerator @ station
+     */
+    public RandomVariate getProcessingTimeGenerator(int station) {
+        return processingTimeGenerator[station];
+    }
+
+    /**
+     * @return the numberAvailableMachines
+     */
+    public int[] getNumberAvailableMachines() {
+        return numberAvailableMachines.clone();
+    }
+
+    /**
+     * @param station
+     * @return the numberAvailableMachines @ station
+     */
+    public int getNumberAvailableMachines(int station) {
+        return numberAvailableMachines[station];
+    }
+
+    /**
+     * @param station
+     * @return the queue @ station
+     */
+    public SortedSet<Part> getQueue(int station) {
+        return new TreeSet<>(queue.get(station));
+    }
+
+    /**
+     * @return the queue
+     */
+    public List<SortedSet<Part>> getQueue() {
+        List<SortedSet<Part>> queueListCopy = new ArrayList<>();
+        for (int station = 0; station < queue.size(); ++station) {
+            queueListCopy.add(getQueue(station));
+        }
+        return queueListCopy;
+    }
+
+    /**
+     * @return the delayInQueue
+     */
+    public double[] getDelayInQueue() {
+        return delayInQueue.clone();
+    }
+
+    /**
+     * @param station
+     * @return the delayInQueue @ station
+     */
+    public double getDelayInQueue(int station) {
+        return delayInQueue[station];
+    }
+
+    /**
+     * @return the timeAtStation
+     */
+    public double[] getTimeAtStation() {
+        return timeAtStation.clone();
+    }
+
+    /**
+     * @param station
+     * @return the timeAtStation @ station
+     */
+    public double getTimeAtStation(int station) {
+        return timeAtStation[station];
+    }
+
+    /**
+     * @return the totalDelayInQueue
+     */
+    public double getTotalDelayInQueue() {
+        return totalDelayInQueue;
+    }
+
+    /**
+     * @return the totalTimeInSystem
+     */
+    public double getTotalTimeInSystem() {
+        return totalTimeInSystem;
+    }
+
+    /**
+     * sets TotalNumberMachines variable
+     *
+     * @param totalNumberMachines
+     */
+    public void setTotalNumberMachines(int[] totalNumberMachines) {
+        this.totalNumberMachines = totalNumberMachines;
+    }
+
+    /**
+     * sets processingTimeGenerator variable
+     *
+     * @param processingTimeGenerator
+     */
+    public void setProcessingTimeGenerator(RandomVariate[] processingTimeGenerator) {
+        this.processingTimeGenerator = processingTimeGenerator;
+    }
+
+    /**
+     * @return the numberComplete
+     */
+    public int getNumberComplete() {
+        return numberComplete;
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/TransientStats.java b/MV3302ClassCode/src/mv3302/TransientStats.java
new file mode 100644
index 0000000000000000000000000000000000000000..9d7bd1901b1acfeb7b89d9d4ef94f83e7ae208f7
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/TransientStats.java
@@ -0,0 +1,53 @@
+package mv3302;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+import simkit.stat.SimpleStatsTally;
+
+/**
+ *
+ * @author dansl
+ */
+public class TransientStats implements PropertyChangeListener {
+
+    private final String state;
+    
+    protected List<SimpleStatsTally> data;
+    
+    protected int nextObs;
+    
+    public TransientStats(String state) {
+        this.state = state;
+        data = new ArrayList<>();
+        nextObs = 0;
+    }
+    
+    
+    public void reset() {
+        nextObs = 0;
+    }
+    
+    @Override
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (!evt.getPropertyName().equals(state)) {
+            return;
+        }
+        if (nextObs >= getRawData().size()) {
+            data.add(new SimpleStatsTally("Data " + nextObs));
+        }
+        if (evt.getNewValue() instanceof Number) {
+            data.get(nextObs).newObservation(((Number)evt.getNewValue()).doubleValue());
+        }
+        nextObs += 1;
+    }
+
+    /**
+     * @return the data
+     */
+    public List<SimpleStatsTally> getRawData() {
+        return new ArrayList<>(data);
+    }
+    
+}
diff --git a/MV3302ClassCode/src/mv3302/TwoCranesBerth.java b/MV3302ClassCode/src/mv3302/TwoCranesBerth.java
new file mode 100644
index 0000000000000000000000000000000000000000..982539d92074d07e334a94e92c864b86049e596b
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/TwoCranesBerth.java
@@ -0,0 +1,209 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
+ */
+package mv3302;
+
+import static java.lang.Double.NaN;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import simkit.SimEntityBase;
+
+/**
+ * The TwoCranesBerth class models a container terminal berth with two cranes.
+ * It keeps track of ships waiting to unload, ships in the berths, and their
+ * corresponding wait times and time in system. The class extends SimEntityBase.
+ *
+ * @author dansl
+ *
+ */
+public class TwoCranesBerth extends SimEntityBase {
+
+    protected SortedSet<Ship> queue;
+    protected SortedSet<Ship> berths;
+    protected double delayInQueue;
+    protected double timeInSystem;
+
+    /**
+     * Initializes the queue and the berths as empty.
+     */
+    public TwoCranesBerth() {
+        queue = new TreeSet<>();
+        berths = new TreeSet<>();
+    }
+
+    /**
+     * Clears the queue, sets the delay and time in system to NaN.
+     */
+    @Override
+    public void reset() {
+        getQueue().clear();
+        delayInQueue = NaN;
+        timeInSystem = NaN;
+    }
+
+    /**
+     * Clears the queue and the berths, sets the delay and time in system to
+     * NaN.
+     */
+    public void doRun() {
+        queue.clear();
+        berths.clear();
+        delayInQueue = NaN;
+        timeInSystem = NaN;
+    }
+
+    /**
+     * Adds a ship to the queue, stamps its arrival time, and fires a property
+     * change event for the queue. If there is only one ship in the berths, it
+     * waits for a delay to simulate the switch to one crane. If the berths are
+     * empty, it waits for a delay to simulate the start of the unloading
+     * process with two cranes.
+     *
+     * @param ship the ship that has arrived at the berth
+     */
+    public void doArrival(Ship ship) {
+        ship.stampTime();
+        SortedSet<Ship> oldQueue = getQueue();
+        queue.add(ship);
+        firePropertyChange("queue", oldQueue, getQueue());
+        if (berths.size() == 1) {
+            waitDelay("SwitchTo1Crane", 0.0);
+        }
+        if (berths.isEmpty()) {
+            waitDelay("StartUnload2Cranes", 0.0);
+        }
+    }
+
+    /**
+     * Unloads a ship with one crane. Removes the ship from the berths, updates
+     * the time in system, and waits for the next ship to start unloading. If
+     * there are no more ships in the queue, it waits for a delay to simulate
+     * the switch to two cranes.
+     *
+     * @param ship the ship being unloaded
+     */
+    public void doSwitchTo1Crane() {
+        Ship ship = berths.first();
+        ship.work(2);
+        ship.stampTime();
+        interrupt("EndUnload2Cranes");
+        waitDelay("StartUnload1Crane", 0.0);
+        waitDelay("EndUnload1Crane", ship.getRemainingUnloadingTime(), ship);
+    }
+
+    /**
+     * Starts unloading a ship with one crane and updates the queue, berths, and
+     * delayInQueue properties.
+     */
+    public void doStartUnload1Crane() {
+        SortedSet<Ship> oldQueue = getQueue();
+        Ship ship = queue.first();
+        queue.remove(ship);
+        firePropertyChange("queue", oldQueue, getQueue());
+        double oldDelayInQueue = getDelayInQueue();
+        delayInQueue = ship.getElapsedTime();
+        firePropertyChange("delayInQueue", oldDelayInQueue, getDelayInQueue());
+        ship.stampTime();
+        SortedSet<Ship> oldBerths = getBerths();
+        berths.add(ship);
+        firePropertyChange("berths", oldBerths, getBerths());
+        waitDelay("EndUnload1Crane", ship.getRemainingUnloadingTime(), ship);
+    }
+
+    /**
+     * Starts unloading a ship with two cranes and updates the queue, berths,
+     * and delayInQueue properties.
+     */
+    public void doStartUnload2Cranes() {
+        SortedSet<Ship> oldQueue = getQueue();
+        Ship ship = queue.first();
+        queue.remove(ship);
+        firePropertyChange("queue", oldQueue, getQueue());
+        double oldDelayInQueue = getDelayInQueue();
+        delayInQueue = ship.getElapsedTime();
+        firePropertyChange("delayInQueue", oldDelayInQueue, getDelayInQueue());
+        ship.stampTime();
+        SortedSet<Ship> oldBerths = getBerths();
+        berths.add(ship);
+        firePropertyChange("berths", oldBerths, getBerths());
+        waitDelay("EndUnload2Cranes", ship.getRemainingUnloadingTime() / 2);
+    }
+
+    /**
+     * Ends the unloading of a ship with one crane, updates the berths and
+     * timeInSystem properties, and checks if there are any remaining ships in
+     * the queue to unload.
+     *
+     * @param ship The ship that is finishing unloading.
+     */
+    public void doEndUnload1Crane(Ship ship) {
+        SortedSet<Ship> oldBerths = getBerths();
+        berths.remove(ship);
+        firePropertyChange("berths", oldBerths, getBerths());
+        double oldTimeInSystem = getTimeInSystem();
+        timeInSystem = ship.getAge();
+        firePropertyChange("timeInSystem", oldTimeInSystem, getTimeInSystem());
+        if (!queue.isEmpty()) {
+            waitDelay("StartUnload1Crane", 0.0);
+        }
+        if (queue.isEmpty()) {
+            waitDelay("SwitchTo2Cranes", 0.0);
+        }
+    }
+
+    /**
+     * Ends the unloading of a ship with two cranes and updates the berths and
+     * timeInSystem properties.
+     */
+    public void doEndUnload2Cranes() {
+        SortedSet<Ship> oldBerths = getBerths();
+        Ship ship = berths.first();
+        berths.remove(ship);
+        firePropertyChange("berths", oldBerths, getBerths());
+        double oldTimeInSystem = getTimeInSystem();
+        timeInSystem = ship.getAge();
+        firePropertyChange("timeInSystem", oldTimeInSystem, getTimeInSystem());
+    }
+
+    /**
+     * Switches to two cranes unloading and updates the ship's time stamps.
+     */
+    public void doSwitchTo2Cranes() {
+        Ship ship = berths.first();
+        ship.work(1);
+        ship.stampTime();
+        waitDelay("EndUnload2Cranes", ship.getRemainingUnloadingTime() / 2);
+        interrupt("EndUnload1Crane", ship);
+    }
+
+    /**
+     * @return the queue
+     */
+    public SortedSet<Ship> getQueue() {
+        return queue;
+    }
+
+    /**
+     * @return the berths
+     */
+    public SortedSet<Ship> getBerths() {
+        return berths;
+    }
+
+    /**
+     * @return the delayInQueue
+     */
+    public double getDelayInQueue() {
+        double delayInQueueCopy = delayInQueue;
+        return delayInQueueCopy;
+    }
+
+    /**
+     * @return the timeInSystem
+     */
+    public double getTimeInSystem() {
+        double timeInSystemCopy = timeInSystem;
+        return timeInSystemCopy;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment6.java b/MV3302ClassCode/src/mv3302/run/Assignment6.java
new file mode 100644
index 0000000000000000000000000000000000000000..c1a4392cbe877cfd40262dc29c6d988125fb971f
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment6.java
@@ -0,0 +1,94 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
+ */
+package mv3302.run;
+
+import java.awt.geom.Point2D;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.SimplePatrolMoverManager;
+import mv3302.SimpleRandomMoverManager;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment6 {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        Point2D initialLocation = new Point2D.Double(0.0, 250.0);
+        double maxSpeed = 30.0;
+
+        SimpleMover simpleMover = new SimpleMover(initialLocation, maxSpeed);
+        System.out.println(simpleMover);
+
+        Point2D[] path = new Point2D[]{
+            new Point2D.Double(-200.0, 0.0),
+            new Point2D.Double(-200.0, 250.0),
+            new Point2D.Double(200.0, 250.0),
+            new Point2D.Double(0.0, 250.0)};
+
+        SimplePathMoverManager simplePathMoverManager = new SimplePathMoverManager(path, true);
+        System.out.println(simplePathMoverManager);
+
+        Point2D initialLocation2 = new Point2D.Double(0.0, 150.0);
+        double maxSpeed2 = 40.0;
+        SimpleMover simpleMover2 = new SimpleMover(initialLocation2, maxSpeed2);
+        System.out.println(simpleMover2);
+
+        Point2D[] path2 = new Point2D[]{
+            new Point2D.Double(0.0, 300.0),
+            new Point2D.Double(0.0, -100.0)};
+
+        SimplePatrolMoverManager simplePatrolMoverManager = new SimplePatrolMoverManager(path2, true);
+        System.out.println(simplePatrolMoverManager);
+
+        //        The coordinate generators
+        RandomVariate[] coordinateGenerator = new RandomVariate[]{
+            RandomVariateFactory.getInstance("Uniform", -250.0, 250.0),
+            RandomVariateFactory.getInstance("Uniform", -100, 300.0)
+        };
+//        Note startOnRun is now true
+        SimpleRandomMoverManager simpleRandomMoverManager = new SimpleRandomMoverManager(coordinateGenerator,
+                true);
+        System.out.println(simpleRandomMoverManager);
+
+        Point2D initialLocation3 = new Point2D.Double(0.0, 0.0);
+        double maxSpeed3 = 50.0;
+        SimpleMover simpleMover3 = new SimpleMover(initialLocation3, maxSpeed3);
+        System.out.println(simpleMover3);
+
+        simpleMover.addSimEventListener(simplePathMoverManager);
+        simplePathMoverManager.addSimEventListener(simpleMover);
+
+        simpleMover.addSimEventListener(simplePatrolMoverManager);
+        simplePatrolMoverManager.addSimEventListener(simpleMover);
+
+        simpleMover.addSimEventListener(simpleRandomMoverManager);
+        simpleRandomMoverManager.addSimEventListener(simpleMover);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper();
+        simpleMover.addPropertyChangeListener(simplePropertyDumper);
+        simplePathMoverManager.addPropertyChangeListener(simplePropertyDumper);
+
+        Schedule.setVerbose(true);
+
+        Schedule.stopAtTime(10.5);
+        Schedule.reset();
+        simpleMover.waitDelay("MoveTo", 0.0);
+        simpleMover.waitDelay("OrderStop", 0.1);
+        simpleMover.waitDelay("Stop", 0.2);
+        simplePatrolMoverManager.waitDelay("Stop", 10.0);
+        simpleRandomMoverManager.waitDelay("Stop", 20.0);
+        Schedule.startSimulation();
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7ConstantRate1Mover.java b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantRate1Mover.java
new file mode 100644
index 0000000000000000000000000000000000000000..d719930c31136b655a9e6aa67e8ac2da852680c3
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantRate1Mover.java
@@ -0,0 +1,68 @@
+
+package mv3302.run;
+
+import java.awt.geom.Point2D;
+import java.util.Arrays;
+import mv3302.SimpleConstantRateMediator;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.SimpleReferee;
+import mv3302.sensor.SimpleConstantRateSensor;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment7ConstantRate1Mover {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        RandomVariate exponentialGenerator = RandomVariateFactory.getInstance("Exponential", .7);
+        Mover[] targets = new Mover[]{
+            new SimpleMover(new Point2D.Double(30.0, 40.0), 20.0),
+            new SimpleMover(new Point2D.Double(0, 0), 20.0)
+        };
+
+        Point2D[] targetPath = new Point2D[]{new Point2D.Double(-30.0, -40.0), new Point2D.Double(60.0, 80.0)};
+        Point2D[] sensorPath = new Point2D[]{new Point2D.Double(30.0, 40.0)};
+        SimplePathMoverManager[] targetMoverManager = new SimplePathMoverManager[]{
+            new SimplePathMoverManager(targetPath, true),
+            new SimplePathMoverManager(sensorPath, true)
+        };
+
+        Sensor[] sensors = new Sensor[targets.length];
+        double meanTimeToDetect = 5.0;
+        sensors[0] = new SimpleConstantRateSensor(targets[0], 30, meanTimeToDetect);
+        sensors[1] = new SimpleConstantRateSensor(targets[1], 40, meanTimeToDetect);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+        for (Sensor sensor : sensors) {
+            sensor.addPropertyChangeListener(simplePropertyDumper);
+        }
+
+        for (int i = 0; i < targets.length; ++i) {
+            targets[i].addSimEventListener(targetMoverManager[i]);
+            targetMoverManager[i].addSimEventListener(targets[i]);
+        }
+
+        SimpleReferee simpleReferee = new SimpleReferee(Arrays.asList(sensors),
+                Arrays.asList(targets));
+        System.out.println(simpleReferee);
+
+        SimpleConstantRateMediator simpleConstantRateMediator = new SimpleConstantRateMediator(exponentialGenerator);
+        simpleReferee.addSimEventListener(simpleConstantRateMediator);
+
+        Schedule.setVerbose(true);
+        Schedule.reset();
+        Schedule.startSimulation();
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7ConstantRate2Movers.java b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantRate2Movers.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb42759d542ca47ed18d63b57659d09eed521a77
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantRate2Movers.java
@@ -0,0 +1,88 @@
+
+package mv3302.run;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.List;
+import mv3302.SimpleConstantRateMediator;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.SimpleReferee;
+import mv3302.sensor.AbstractSimpleSensor;
+import mv3302.sensor.SimpleConstantRateSensor;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment7ConstantRate2Movers {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        RandomVariate exponentialGenerator = RandomVariateFactory.getInstance("Exponential", .7);
+        SimpleMover mover1 = new SimpleMover(new Point2D.Double(-20.0, 0.0), 30.0);
+        AbstractSimpleSensor sensor1 = new SimpleConstantRateSensor(mover1, 20.0, 5.0);
+        Point2D[] moverPath1 = new Point2D[]{
+            new Point2D.Double(100.0, 0.0)
+        };
+        SimplePathMoverManager moverManager1 = new SimplePathMoverManager(moverPath1, true);
+        
+        mover1.addSimEventListener(moverManager1);
+        moverManager1.addSimEventListener(mover1);
+        
+        SimpleMover mover2 = new SimpleMover(new Point2D.Double(50.0, 0.0), 40.0);
+        AbstractSimpleSensor sensor2 = new SimpleConstantRateSensor(mover2, 30.0, 5.0);
+        Point2D[] moverPath2 = new Point2D[] {
+            new Point2D.Double(-100.0, 0.0)
+        };
+        SimplePathMoverManager moverManager2 = new SimplePathMoverManager(moverPath2, true);
+        mover2.addSimEventListener(moverManager2);
+        moverManager2.addSimEventListener(mover2);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+        mover1.addPropertyChangeListener(simplePropertyDumper);
+        moverManager1.addPropertyChangeListener(simplePropertyDumper);
+        sensor1.addPropertyChangeListener(simplePropertyDumper);
+        
+        mover2.addPropertyChangeListener(simplePropertyDumper);
+        moverManager2.addPropertyChangeListener(simplePropertyDumper);
+        sensor2.addPropertyChangeListener(simplePropertyDumper);
+        
+        List<Mover> targets = new ArrayList<>();
+        targets.add(mover1);
+        targets.add(mover2);
+        
+        List<Sensor> sensors = new ArrayList<>();
+        sensors.add(sensor1);
+        sensors.add(sensor2);
+        
+        SimpleReferee referee = new SimpleReferee(sensors, targets);
+        
+        SimpleConstantRateMediator mediator1 = new SimpleConstantRateMediator(exponentialGenerator);
+        referee.addSimEventListener(mediator1);
+        
+        System.out.println(mover1.paramString());
+        System.out.println(moverManager1);
+        System.out.println(sensor1.paramString());
+        
+        System.out.println(mover2.paramString());
+        System.out.println(moverManager2);
+        System.out.println(sensor2.paramString());
+        
+        System.out.println(referee);
+        
+        Schedule.setVerbose(true);
+        
+        Schedule.reset();
+        Schedule.startSimulation();
+        
+    }
+    
+}
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7ConstantTime1Mover.java b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantTime1Mover.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b9e12a506e41ad31d8d9289a62c3889b2d79173
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantTime1Mover.java
@@ -0,0 +1,65 @@
+
+package mv3302.run;
+
+import java.awt.geom.Point2D;
+import java.util.Arrays;
+import mv3302.SimpleConstantTimeMediator;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.SimpleReferee;
+import mv3302.sensor.SimpleConstantTimeSensor;
+import simkit.Schedule;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment7ConstantTime1Mover {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+       Mover[] targets = new Mover[]{
+            new SimpleMover(new Point2D.Double(30.0, 40.0), 20.0), 
+            new SimpleMover(new Point2D.Double(0, 0), 20.0)
+        };
+
+        Point2D[] targetPath = new Point2D[]{new Point2D.Double(-30.0, -40.0), new Point2D.Double(60.0, 80.0)};
+        Point2D[] sensorPath = new Point2D[]{new Point2D.Double(30.0, 40.0)};
+        SimplePathMoverManager[] targetMoverManager = new SimplePathMoverManager[]{
+            new SimplePathMoverManager(targetPath, true),
+            new SimplePathMoverManager(sensorPath, true)
+        };
+
+        Sensor[] sensors = new Sensor[targets.length];
+        double timeToDetect = 5.0;
+        sensors[0] = new SimpleConstantTimeSensor(targets[0], 30, timeToDetect);
+        sensors[1] = new SimpleConstantTimeSensor(targets[1], 40, timeToDetect);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+        for (Sensor sensor: sensors) {
+            sensor.addPropertyChangeListener(simplePropertyDumper);
+        }
+        
+        for (int i = 0; i < targets.length; ++i) {
+            targets[i].addSimEventListener(targetMoverManager[i]);
+            targetMoverManager[i].addSimEventListener(targets[i]);
+        }
+
+        SimpleReferee simpleReferee = new SimpleReferee(Arrays.asList(sensors),
+                Arrays.asList(targets));
+        System.out.println(simpleReferee);
+        
+        SimpleConstantTimeMediator simpleConstantTimeMediator = new SimpleConstantTimeMediator();
+        simpleReferee.addSimEventListener(simpleConstantTimeMediator);
+
+        Schedule.setVerbose(true);
+        Schedule.reset();
+        Schedule.startSimulation();
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7ConstantTime2Movers.java b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantTime2Movers.java
new file mode 100644
index 0000000000000000000000000000000000000000..31a8d854d972323c42803b9480991fe8b11f03b8
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment7ConstantTime2Movers.java
@@ -0,0 +1,87 @@
+
+package mv3302.run;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.List;
+import mv3302.SimpleConstantTimeMediator;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.SimpleReferee;
+import mv3302.sensor.AbstractSimpleSensor;
+import mv3302.sensor.SimpleConstantTimeSensor;
+import simkit.Schedule;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment7ConstantTime2Movers {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        
+        SimpleMover mover1 = new SimpleMover(new Point2D.Double(-20.0, 0.0), 30.0);
+        AbstractSimpleSensor sensor1 = new SimpleConstantTimeSensor(mover1, 20.0, 5.0);
+        Point2D[] moverPath1 = new Point2D[]{
+            new Point2D.Double(100.0, 0.0)
+        };
+        SimplePathMoverManager moverManager1 = new SimplePathMoverManager(moverPath1, true);
+        
+        mover1.addSimEventListener(moverManager1);
+        moverManager1.addSimEventListener(mover1);
+        
+        SimpleMover mover2 = new SimpleMover(new Point2D.Double(50.0, 0.0), 40.0);
+        AbstractSimpleSensor sensor2 = new SimpleConstantTimeSensor(mover2, 30.0, 5.0);
+        Point2D[] moverPath2 = new Point2D[] {
+            new Point2D.Double(-100.0, 0.0)
+        };
+        SimplePathMoverManager moverManager2 = new SimplePathMoverManager(moverPath2, true);
+        mover2.addSimEventListener(moverManager2);
+        moverManager2.addSimEventListener(mover2);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+        mover1.addPropertyChangeListener(simplePropertyDumper);
+        moverManager1.addPropertyChangeListener(simplePropertyDumper);
+        sensor1.addPropertyChangeListener(simplePropertyDumper);
+        
+        mover2.addPropertyChangeListener(simplePropertyDumper);
+        moverManager2.addPropertyChangeListener(simplePropertyDumper);
+        sensor2.addPropertyChangeListener(simplePropertyDumper);
+        
+        List<Mover> targets = new ArrayList<>();
+        targets.add(mover1);
+        targets.add(mover2);
+        
+        List<Sensor> sensors = new ArrayList<>();
+        sensors.add(sensor1);
+        sensors.add(sensor2);
+        
+        SimpleReferee referee = new SimpleReferee(sensors, targets);
+        
+        SimpleConstantTimeMediator mediator1 = new SimpleConstantTimeMediator();
+        referee.addSimEventListener(mediator1);
+        
+        System.out.println(mover1.paramString());
+        System.out.println(moverManager1);
+        System.out.println(sensor1.paramString());
+        
+        System.out.println(mover2.paramString());
+        System.out.println(moverManager2);
+        System.out.println(sensor2.paramString());
+        
+        System.out.println(referee);
+        
+        Schedule.setVerbose(true);
+        
+        Schedule.reset();
+        Schedule.startSimulation();
+        
+    }
+    
+}
+
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7CookieSensor1Mover.java b/MV3302ClassCode/src/mv3302/run/Assignment7CookieSensor1Mover.java
new file mode 100644
index 0000000000000000000000000000000000000000..c8def5be9582dd1022fd10fa0918d863949e02ef
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment7CookieSensor1Mover.java
@@ -0,0 +1,65 @@
+
+package mv3302.run;
+
+import java.awt.geom.Point2D;
+import java.util.Arrays;
+import mv3302.SimpleCookieCutterMediator;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.SimpleReferee;
+import mv3302.sensor.SimpleCookieCutterSensor;
+import simkit.Schedule;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment7CookieSensor1Mover {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+
+        Mover[] targets = new Mover[]{
+            new SimpleMover(new Point2D.Double(30.0, 40.0), 20.0), 
+            new SimpleMover(new Point2D.Double(0, 0), 20.0)
+        };
+
+        Point2D[] targetPath = new Point2D[]{new Point2D.Double(-30.0, -40.0), new Point2D.Double(60.0, 80.0)};
+        Point2D[] sensorPath = new Point2D[]{new Point2D.Double(30.0, 40.0)};
+        SimplePathMoverManager[] targetMoverManager = new SimplePathMoverManager[]{
+            new SimplePathMoverManager(targetPath, true),
+            new SimplePathMoverManager(sensorPath, true)
+        };
+
+        Sensor[] sensors = new Sensor[targets.length];
+        sensors[0] = new SimpleCookieCutterSensor(targets[0], 30);
+        sensors[1] = new SimpleCookieCutterSensor(targets[1], 40);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+        for (Sensor sensor: sensors) {
+            sensor.addPropertyChangeListener(simplePropertyDumper);
+        }
+        
+        for (int i = 0; i < targets.length; ++i) {
+            targets[i].addSimEventListener(targetMoverManager[i]);
+            targetMoverManager[i].addSimEventListener(targets[i]);
+        }
+
+        SimpleReferee simpleReferee = new SimpleReferee(Arrays.asList(sensors),
+                Arrays.asList(targets));
+        System.out.println(simpleReferee);
+        
+        SimpleCookieCutterMediator simpleCookieCutterMediator = new SimpleCookieCutterMediator();
+        simpleReferee.addSimEventListener(simpleCookieCutterMediator);
+
+        Schedule.setVerbose(true);
+        Schedule.reset();
+        Schedule.startSimulation();
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/run/Assignment7CookieSensor2Movers.java b/MV3302ClassCode/src/mv3302/run/Assignment7CookieSensor2Movers.java
new file mode 100644
index 0000000000000000000000000000000000000000..2745cdf90e06a050a36c8ff5f3069e139065b68e
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/Assignment7CookieSensor2Movers.java
@@ -0,0 +1,86 @@
+package mv3302.run;
+
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.List;
+import mv3302.SimpleCookieCutterMediator;
+import mv3302.SimpleMover;
+import mv3302.SimplePathMoverManager;
+import mv3302.SimpleReferee;
+import mv3302.sensor.AbstractSimpleSensor;
+import mv3302.sensor.SimpleCookieCutterSensor;
+import simkit.Schedule;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class Assignment7CookieSensor2Movers {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        
+        SimpleMover mover1 = new SimpleMover(new Point2D.Double(-20.0, 0.0), 30.0);
+        AbstractSimpleSensor sensor1 = new SimpleCookieCutterSensor(mover1, 20.0);
+        Point2D[] moverPath1 = new Point2D[]{
+            new Point2D.Double(100.0, 0.0)
+        };
+        SimplePathMoverManager moverManager1 = new SimplePathMoverManager(moverPath1, true);
+        
+        mover1.addSimEventListener(moverManager1);
+        moverManager1.addSimEventListener(mover1);
+        
+        SimpleMover mover2 = new SimpleMover(new Point2D.Double(50.0, 0.0), 40.0);
+        AbstractSimpleSensor sensor2 = new SimpleCookieCutterSensor(mover2, 30.0);
+        Point2D[] moverPath2 = new Point2D[] {
+            new Point2D.Double(-100.0, 0.0)
+        };
+        SimplePathMoverManager moverManager2 = new SimplePathMoverManager(moverPath2, true);
+        mover2.addSimEventListener(moverManager2);
+        moverManager2.addSimEventListener(mover2);
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+        mover1.addPropertyChangeListener(simplePropertyDumper);
+        moverManager1.addPropertyChangeListener(simplePropertyDumper);
+        sensor1.addPropertyChangeListener(simplePropertyDumper);
+        
+        mover2.addPropertyChangeListener(simplePropertyDumper);
+        moverManager2.addPropertyChangeListener(simplePropertyDumper);
+        sensor2.addPropertyChangeListener(simplePropertyDumper);
+        
+        List<Mover> targets = new ArrayList<>();
+        targets.add(mover1);
+        targets.add(mover2);
+        
+        List<Sensor> sensors = new ArrayList<>();
+        sensors.add(sensor1);
+        sensors.add(sensor2);
+        
+        SimpleReferee referee = new SimpleReferee(sensors, targets);
+        
+        SimpleCookieCutterMediator mediator1 = new SimpleCookieCutterMediator();
+        referee.addSimEventListener(mediator1);
+        
+        System.out.println(mover1.paramString());
+        System.out.println(moverManager1);
+        System.out.println(sensor1.paramString());
+        
+        System.out.println(mover2.paramString());
+        System.out.println(moverManager2);
+        System.out.println(sensor2.paramString());
+        
+        System.out.println(referee);
+        
+        Schedule.setVerbose(true);
+        
+        Schedule.reset();
+        Schedule.startSimulation();
+        
+    }
+    
+}
diff --git a/MV3302ClassCode/src/mv3302/run/RunArrivalProcess.java b/MV3302ClassCode/src/mv3302/run/RunArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..3ff2aa3202c10d8d5458e91b461c88c27329a9b9
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/RunArrivalProcess.java
@@ -0,0 +1,48 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
+ */
+package mv3302.run;
+
+import mv3302.ArrivalProcess;
+import simkit.Schedule;
+import simkit.random.RandomVariateFactory;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ * Class runs and tests methods associated with the functioning of the
+ * ArrivalProcess class
+ *
+ * @author dansl
+ */
+public class RunArrivalProcess {
+
+    /**
+     * main class starts the program to check functionality
+     *
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+
+        //hard codes the Exponential value for the time to 3.2
+        var interarrivalTimeGenerator = RandomVariateFactory.getInstance("Exponential", 3.2);
+        //Initiates the Arrival Process based on the generated time value
+        ArrivalProcess arrivalProcess = new ArrivalProcess(interarrivalTimeGenerator);
+        System.out.println(arrivalProcess);
+
+        //Programs the schedule to stop at the 15 second mark 
+        Schedule.stopAtTime(15.0);
+        Schedule.setVerbose(true);
+
+        Schedule.reset();
+        Schedule.startSimulation();
+
+        //Prints finalized counts based on the simulation run time
+        System.out.println("At time " + Schedule.getSimTime() + " there have been " + arrivalProcess.getNumberArrivals() + " arrivals");
+
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper();
+        arrivalProcess.addPropertyChangeListener(simplePropertyDumper);
+
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/run/RunServerWithReneges.java b/MV3302ClassCode/src/mv3302/run/RunServerWithReneges.java
new file mode 100644
index 0000000000000000000000000000000000000000..555f1341315466d515b7aa19a7bcea8f977067da
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/RunServerWithReneges.java
@@ -0,0 +1,97 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
+ */
+package mv3302.run;
+
+import mv3302.CustomerArrivalProcess;
+import mv3302.ServerWithReneges;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.stat.CollectionSizeTimeVaryingStats;
+import simkit.stat.SimpleStatsTally;
+import simkit.stat.SimpleStatsTimeVarying;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ * Simple test of ServerWithReneges calculating for Number of Arrivals, Number
+ * Served, Number Reneges, Percent Reneges Average number in queue, Average
+ * Utilization, Avg Delay in Queue Served, Avg Delay in Queue Reneged, and Avg
+ * Time in System
+ */
+public class RunServerWithReneges {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+//        Instantiate CustomerArrivalProcess
+        RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance("Exponential", 1.5);
+        RandomVariate serviceTimeGenerator = RandomVariateFactory.getInstance("Gamma", 2.5, 1.2);
+        RandomVariate renegeTimeGenerator = RandomVariateFactory.getInstance("Uniform", 4.0, 6.0);
+        CustomerArrivalProcess renegingCustomerArrivalProcess = new CustomerArrivalProcess(renegeTimeGenerator, interarrivalTimeGenerator, serviceTimeGenerator);
+        System.out.println(renegingCustomerArrivalProcess);
+//        Instantiate ServerWithReneges
+        int totalNumberServers = 2;
+
+        ServerWithReneges serverWithReneges = new ServerWithReneges(totalNumberServers, serviceTimeGenerator);
+        System.out.println(serverWithReneges);
+
+//        The ServerWithReneges will "hear" Arrival(Customer) events
+        renegingCustomerArrivalProcess.addSimEventListener(serverWithReneges);
+
+//        This was used for debugging model
+        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+
+//        This listener computes time-varying statictics for Collection states
+        CollectionSizeTimeVaryingStats numberInQueueStat = new CollectionSizeTimeVaryingStats("queue");
+        serverWithReneges.addPropertyChangeListener(numberInQueueStat);
+
+//        Same as SimpleServer model
+        SimpleStatsTimeVarying numberAvailableServersStat = new SimpleStatsTimeVarying("numberAvailableServers");
+        serverWithReneges.addPropertyChangeListener(numberAvailableServersStat);
+
+//        Tally statistics are computed in the same way by "listening" 
+        SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem");
+        serverWithReneges.addPropertyChangeListener(timeInSystemStat);
+
+        SimpleStatsTally delayInQueueServedStat = new SimpleStatsTally("delayInQueueServed");
+        serverWithReneges.addPropertyChangeListener(delayInQueueServedStat);
+
+        SimpleStatsTally delayInQueueRenegedStat = new SimpleStatsTally("delayInQueueReneged");
+        serverWithReneges.addPropertyChangeListener(delayInQueueRenegedStat);
+
+//        Commented out after model debugged
+//        renegingCustomerArrivalProcess.addPropertyChangeListener(simplePropertyDumper);
+//        serverWithReneges.addPropertyChangeListener(simplePropertyDumper);
+//        Was "true" when debugging model
+        Schedule.setVerbose(false);
+//        Schedule.stopOnEvent(5, "EndService", Entity.class);
+
+//        Run for 100,000 time units
+        double stopTime = 100000.0;
+        Schedule.stopAtTime(stopTime);
+
+//        Initialized & run 
+        Schedule.reset();
+        Schedule.startSimulation();
+
+        System.out.printf("%nSimulation ended at time %,.2f%n%n", Schedule.getSimTime());
+
+        System.out.printf("Number Arrivals: %,d%n", renegingCustomerArrivalProcess.getNumberArrivals());
+        System.out.printf("Number Served: %,d%n", serverWithReneges.getNumberServed());
+        System.out.printf("Number Reneges: %,d%n", renegingCustomerArrivalProcess.getNumberArrivals() - serverWithReneges.getNumberServed());
+        double percentReneges = (double) (renegingCustomerArrivalProcess.getNumberArrivals() - serverWithReneges.getNumberServed()) / renegingCustomerArrivalProcess.getNumberArrivals() * 100.00;
+        System.out.printf("Percent Reneges: %,.2f%%%n", percentReneges);
+
+        System.out.printf("Avg # in Queue: %,.3f%n", numberInQueueStat.getMean());
+        System.out.printf("Avg Utilization: %,.3f%n%n", numberAvailableServersStat.getMean());
+
+//        From directly computing delay in queue, delay in reneged and time in system
+        System.out.printf("Avg Delay in Queue Served: %,.3f%n", delayInQueueServedStat.getMean());
+        System.out.printf("Avg Delay in Queue Reneged: %,.3f%n", delayInQueueRenegedStat.getMean());
+        System.out.printf("Avg Time in System (Served): %,.3f%n", timeInSystemStat.getMean());
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/run/RunSimpleServer.java b/MV3302ClassCode/src/mv3302/run/RunSimpleServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e3a4b0c107406aaf9b0fae437f834af82f38c28
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/RunSimpleServer.java
@@ -0,0 +1,63 @@
+package mv3302.run;
+
+import mv3302.ArrivalProcess;
+import mv3302.SimpleServer;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.stat.SimpleStatsTimeVarying;
+
+/**
+ *
+ * @author dansl
+ */
+public class RunSimpleServer {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        //Creates a random variate and assigns that value to the interarrival time variable
+        RandomVariate interarrivalTime = RandomVariateFactory.getInstance("Uniform", 0.9, 2.2);
+        //Creates an instance variable of the arrival process
+        ArrivalProcess arrivalProcess = new ArrivalProcess(interarrivalTime);
+        //Prints out pertinent information about the arrival process in the sim
+        System.out.println(arrivalProcess);
+
+        //Creates a random variate with the following properties
+        String rvName = "Gamma";
+        double alpha = 1.7;
+        double beta = 1.8;
+        RandomVariate serviceTime = RandomVariateFactory.getInstance(rvName, alpha, beta);
+
+        //Creates a simple server with two servers and varying service times
+        SimpleServer simpleServer = new SimpleServer(2, serviceTime);
+        //Prints pertinent simple server details
+        System.out.println(simpleServer);
+        //Adds a sim event listener on the simple server for changes in the arrival process
+        arrivalProcess.addSimEventListener(simpleServer);
+
+        //Creates statistics tracking stats of pertinent variable changes in the simulation over time
+        SimpleStatsTimeVarying numberInQueueStat = new SimpleStatsTimeVarying("numberInQueue");
+        SimpleStatsTimeVarying numberAvailableServersStat = new SimpleStatsTimeVarying("numberAvailableServers");
+
+        //Sets statistics objects as listeners to state changes in the simple server
+        simpleServer.addPropertyChangeListener(numberInQueueStat);
+        simpleServer.addPropertyChangeListener(numberAvailableServersStat);
+        //Display each event & the Event List if value is set to true
+        Schedule.setVerbose(false);
+        //End at the given simulation time
+        Schedule.stopAtTime(100000.0);
+        //Invoke reset() on the Simkit component(s)
+        Schedule.reset();
+        //Execute the simulation
+        Schedule.startSimulation();
+
+        //Prints out final simulation statistics by pulling necessary values
+        System.out.printf("Simulation ended at time %,.3f%n", Schedule.getSimTime());
+        System.out.printf("%nThere have been %d arrivals%n", arrivalProcess.getNumberArrivals());
+        System.out.printf("There have been %d customers served%n", simpleServer.getNumberServed());
+        System.out.printf("Average number in queue\t%.3f%n", numberInQueueStat.getMean());
+        System.out.printf("Average utilization\t%.3f%n", 1.0 - numberAvailableServersStat.getMean() / simpleServer.getTotalNumberServers());
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/run/RunSteadyStateAnalysis.java b/MV3302ClassCode/src/mv3302/run/RunSteadyStateAnalysis.java
new file mode 100644
index 0000000000000000000000000000000000000000..51a6b72b76e6c6d1e0a64c432ba3c017257f980f
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/RunSteadyStateAnalysis.java
@@ -0,0 +1,79 @@
+package mv3302.run;
+
+import static java.lang.Math.sqrt;
+import mv3302.PartArrivalProcess;
+import mv3302.TransferLineComponent;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.stat.SimpleStatsTally;
+import simkit.stat.StudentT;
+import simkit.stat.TruncatingSimpleStatsTally;
+
+/**
+ * The main class for running steady state analysis.
+ *
+ * @author dansl
+ */
+public class RunSteadyStateAnalysis {
+
+    /**
+     * The main method for executing the steady state analysis.
+     *
+     * @param args the command line arguments
+     */
+    public static void main(String args[]) {
+        // Create a random variate generator for interarrival times with an exponential distribution and mean of 2.5
+        RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(
+                "Exponential", 2.5);
+        // Create a part arrival process with the interarrival time generator
+        PartArrivalProcess arrivalProcess = new PartArrivalProcess(interarrivalTimeGenerator);
+        // Create an array of random variate generators for processing times
+        RandomVariate[] processingTimeGenerator
+                = {RandomVariateFactory.getInstance("Exponential", 2.4),
+                    RandomVariateFactory.getInstance("Gamma", 3.2, 3.3),
+                    RandomVariateFactory.getInstance("Uniform", 4.5, 6.7),
+                    RandomVariateFactory.getInstance("Exponential", 3.0)};
+        // Create an array of total number of workstations
+        int[] totalNumberWorkstations = new int[4];
+        totalNumberWorkstations[0] = 1;
+        totalNumberWorkstations[1] = 5;
+        totalNumberWorkstations[2] = 4;
+        totalNumberWorkstations[3] = 2;
+        // Create a transfer line component with the processing time generators and total number of workstations
+        TransferLineComponent transferLineComponent = new TransferLineComponent(processingTimeGenerator, totalNumberWorkstations);
+        // Add the transfer line component as a listener to the arrival process
+        arrivalProcess.addSimEventListener(transferLineComponent);
+        int warmup = 1000;
+        int observations = 10000;
+        // Create a statistical tally for tracking delay in queue
+        SimpleStatsTally delayInQueueStat = new TruncatingSimpleStatsTally("delayInQueue", 2000);
+        // Add the delay in queue stat as a property change listener to the transfer line component
+        transferLineComponent.addPropertyChangeListener(delayInQueueStat);
+        System.out.println(arrivalProcess);
+        System.out.println(transferLineComponent);
+        // Create a statistical tally for tracking delay in queue in the outer loop
+        SimpleStatsTally outerDelayInQueueStat = new SimpleStatsTally("outerDelayInQueue");
+        // Stop the simulation after warmup + observations arrivals
+        Schedule.stopOnEvent(warmup + observations, "Arrival");
+        int numberReplications = 50;
+        double alpha = 0.05;
+        // Outer loop for multiple replications
+        System.out.println("Avg Delay In Queue");
+        for (int replication = 1; replication <= numberReplications; ++replication) {
+            // Reset the simulation schedule and delay in queue stat for each replication
+            Schedule.reset();
+            delayInQueueStat.reset();
+            Schedule.startSimulation();
+            // Record the mean delay in queue for the replication in the outer tally
+            outerDelayInQueueStat.newObservation(delayInQueueStat.getMean());
+            // Print the replication number, average delay, and confidence interval
+            System.out.printf("%d %.3f ± %.3f%n",
+                    replication,
+                    outerDelayInQueueStat.getMean(),
+                    outerDelayInQueueStat.getStandardDeviation()
+                    * StudentT.getQuantile(1.0 - 0.5 * alpha, outerDelayInQueueStat.getCount() - 1) / sqrt(outerDelayInQueueStat.getCount())
+            );
+        }
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/run/RunTransferLineComponent.java b/MV3302ClassCode/src/mv3302/run/RunTransferLineComponent.java
new file mode 100644
index 0000000000000000000000000000000000000000..da91a5c3390777c75f720fd766e0962f0fdcea31
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/RunTransferLineComponent.java
@@ -0,0 +1,122 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
+ */
+package mv3302.run;
+
+import mv3302.PartArrivalProcess;
+import mv3302.TransferLineComponent;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.stat.MultipleCollectionSizeTimeVarying;
+import simkit.stat.MultipleSimpleStatsTally;
+import simkit.stat.SimpleStatsTally;
+import simkit.util.SimplePropertyDumper;
+
+/**
+ *
+ * @author dansl
+ */
+public class RunTransferLineComponent {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        //        Instantiate PartArrivalProcess
+        RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance("Exponential", 1.7);
+        PartArrivalProcess arrivalProcess = new PartArrivalProcess(interarrivalTimeGenerator);
+        System.out.println(arrivalProcess);
+
+//        Instantiate TransferLineComponent
+        int[] totalNumberMachines = new int[3];
+        totalNumberMachines[0] = 5;
+        totalNumberMachines[1] = 4;
+        totalNumberMachines[2] = 2;
+        RandomVariate[] processingTimeGenerator = {RandomVariateFactory.getInstance("Gamma", 3.2, 2.3),
+            RandomVariateFactory.getInstance("Uniform", 4.5, 6.7),
+            RandomVariateFactory.getInstance("Exponential", 3.0)};
+        TransferLineComponent transferLineComponent = new TransferLineComponent(processingTimeGenerator, totalNumberMachines);
+        System.out.println(transferLineComponent);
+
+//        The transferLineComponent will "hear" Arrival(part) events
+        arrivalProcess.addSimEventListener(transferLineComponent);
+
+        //        This was used for debugging model
+//        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+//        This listener computes time-varying statistics for multiple Collection states
+        MultipleCollectionSizeTimeVarying numberInQueueStat
+                = new MultipleCollectionSizeTimeVarying("queue");
+        transferLineComponent.addPropertyChangeListener("queue", numberInQueueStat);
+
+        MultipleSimpleStatsTally numberAvailableMachinesStat
+                = new MultipleSimpleStatsTally("numberAvailableMachines");
+        transferLineComponent.addPropertyChangeListener("numberAvailableMachines", numberAvailableMachinesStat);
+
+//        Tally statistics are computed in the same way by "listening" 
+        MultipleSimpleStatsTally timeAtStationStat
+                = new MultipleSimpleStatsTally("timeAtStation");
+        transferLineComponent.addPropertyChangeListener("timeAtStation",
+                timeAtStationStat);
+
+        MultipleSimpleStatsTally delayInQueueStat
+                = new MultipleSimpleStatsTally("delayInQueue");
+        transferLineComponent.addPropertyChangeListener("delayInQueue",
+                delayInQueueStat);
+
+        SimpleStatsTally totalTimeInSystemStat = new SimpleStatsTally("totalTimeInSystem");
+        transferLineComponent.addPropertyChangeListener(totalTimeInSystemStat);
+
+        SimpleStatsTally totalDelayInQueueStat = new SimpleStatsTally("totalDelayInQueue");
+        transferLineComponent.addPropertyChangeListener(totalDelayInQueueStat);
+
+//        arrivalProcess.addPropertyChangeListener(simplePropertyDumper);
+//        transferLineComponent.addPropertyChangeListener(simplePropertyDumper);
+//        Was "true" when debugging model
+        Schedule.setVerbose(false);
+
+//        Run for 500,000 time units        
+        double stopTime = 500000.0;
+        Schedule.stopAtTime(stopTime);
+
+//      Initialized and Run
+        Schedule.reset();
+//Start Running of Simulation
+        Schedule.startSimulation();
+        System.out.printf("%nSimulation ended at time %,.2f%n%n", Schedule.getSimTime());
+
+        System.out.printf("Number arrivals: %5s%n", arrivalProcess.getNumberArrivals());
+        System.out.printf("Number Completed: %4s%n%n", totalTimeInSystemStat.getCount());
+
+        System.out.printf("%15s%15s%15s%15s%15s%n", "", "Avg", "Avg #", "Avg Delay", "Avg Time");
+        System.out.printf("%15s%15s%15s%15s%15s%n", "station", "util", "in Queue", "in Queue", "at Station");
+        double avgNumberInSystem = numberInQueueStat.getMean() + 11
+                - numberAvailableMachinesStat.getMean();
+        double arrivalRate = arrivalProcess.getNumberArrivals() / Schedule.getSimTime();
+        for (int i = 0; i < totalNumberMachines.length; i++) {
+            double utilization = 1.0 - numberAvailableMachinesStat.getMean(i) / transferLineComponent.getTotalNumberMachines(i);
+            double avgNumberInQueue = numberInQueueStat.getMean(i);
+            double avgDelayInQueue = delayInQueueStat.getMean(i);
+            double avgTimeAtStation = timeAtStationStat.getMean(i);
+            System.out.printf("%15d%15.4f%15.4f%15.4f%15.4f%n", i, utilization, avgNumberInQueue, avgDelayInQueue, avgTimeAtStation);
+        }
+        System.out.println();
+        System.out.println("Using Little's Formula");
+        System.out.println();
+        System.out.printf("%15s%15s%15s%n", "", "Avg Delay", "Avg Time");
+        System.out.printf("%15s%15s%15s%n", "station", "in Queue", "at Station");
+        for (int i = 0; i < totalNumberMachines.length; i++) {
+            double avgNumberInQueue = numberInQueueStat.getMean(i);
+            double avgDelayInQueue = delayInQueueStat.getMean(i);
+            double avgTimeAtStation = avgNumberInQueue / arrivalRate;
+            System.out.printf("%15s%15.4f%15.4f%n", i, avgDelayInQueue, avgTimeAtStation);
+        }
+        System.out.println();
+
+        System.out.printf("Avg Time in System: %.4f (Using Little: %.4f)%n", totalTimeInSystemStat.getMean() + totalDelayInQueueStat.getMean(),
+                avgNumberInSystem / arrivalRate);
+        System.out.printf("Avg total delay in queue: %.4f (Using Little: %.4f)%n", totalDelayInQueueStat.getMean(),
+                totalDelayInQueueStat.getMean() - transferLineComponent.getTotalTimeInSystem() * ((1.0 - numberAvailableMachinesStat.getMean()) / totalNumberMachines.length));
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/run/RunTransientAnalysis.java b/MV3302ClassCode/src/mv3302/run/RunTransientAnalysis.java
new file mode 100644
index 0000000000000000000000000000000000000000..156fce31bfaabbe8aeab1d3e322eeb7c2a499f38
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/RunTransientAnalysis.java
@@ -0,0 +1,82 @@
+package mv3302.run;
+
+import static java.lang.Math.sqrt;
+import mv3302.PartArrivalProcess;
+import mv3302.StoppedPartArrivalProcess;
+import mv3302.TransferLineComponent;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.stat.SimpleStatsTally;
+import simkit.stat.StudentT;
+
+/**
+ *
+ * @author dansl
+ */
+public class RunTransientAnalysis {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String args[]) {
+        // Create an exponential random variate generator with a mean of 2.5
+        RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance(
+                "Exponential", 2.5);
+        // Define the stop time for the simulation (in minutes)
+        int stopTime = 480;
+        // Create a part arrival process using the interarrival time generator
+        PartArrivalProcess partArrivalProcess = new PartArrivalProcess(interarrivalTimeGenerator);
+        // Create a stopped part arrival process with the given stop time
+        StoppedPartArrivalProcess stoppedArrivalProcess = new StoppedPartArrivalProcess(stopTime);
+        // Create an array of random variate generators for processing times
+        RandomVariate[] processingTimeGenerator
+                = {RandomVariateFactory.getInstance("Exponential", 2.4), 
+                    RandomVariateFactory.getInstance("Gamma", 3.2, 3.3), 
+                    RandomVariateFactory.getInstance("Uniform", 4.5, 6.7), 
+                    RandomVariateFactory.getInstance("Exponential", 3.0)};
+        // Define the total number of workstations for each type of processing time
+        int[] totalNumberWorkstations = new int[4];
+        totalNumberWorkstations[0] = 1;
+        totalNumberWorkstations[1] = 5;
+        totalNumberWorkstations[2] = 4;
+        totalNumberWorkstations[3] = 2;
+        // Create a transfer line component with the processing time generators and workstation numbers
+        TransferLineComponent transferLineComponent = new TransferLineComponent(processingTimeGenerator, totalNumberWorkstations);
+        // Add the transfer line component as a listener to the part arrival processes
+        partArrivalProcess.addSimEventListener(transferLineComponent);
+        stoppedArrivalProcess.addSimEventListener(transferLineComponent);
+        // Create a statistics tally for total time in the system
+        SimpleStatsTally totalTimeInSystemStat = new SimpleStatsTally("totalTimeInSystem");
+        // Add the statistics tally as a property change listener to the transfer line component
+        transferLineComponent.addPropertyChangeListener(totalTimeInSystemStat);
+
+        System.out.println(partArrivalProcess);
+        System.out.println(stoppedArrivalProcess);
+        System.out.println(transferLineComponent);
+        // Create a statistics tally for outer time in the system
+        SimpleStatsTally outerTimeInSystemStat = new SimpleStatsTally("outerTimeInSystem");
+        // Define the confidence level (alpha)
+        double alpha = 0.05;
+        // Stop the simulation after 10,000 events with the name "Arrival"
+        Schedule.stopOnEvent(10000, "Arrival");
+
+        System.out.println("Avg Delay In Queue");
+        // Run the replications
+        for (int replication = 1; replication <= stopTime; ++replication) {
+            Schedule.reset();
+            // Reset the statistics tally for total time in the system
+            totalTimeInSystemStat.reset();
+            Schedule.startSimulation();
+            // Record the outer time in the system using the mean of the total time in the system
+            outerTimeInSystemStat.newObservation(totalTimeInSystemStat.getMean());
+            // Print the replication number, mean, and confidence interval
+            System.out.printf("%d %.3f ± %.3f%n",
+                    replication,
+                    outerTimeInSystemStat.getMean(),
+                    outerTimeInSystemStat.getStandardDeviation()
+                    * StudentT.getQuantile(1.0 - 0.5 * alpha, outerTimeInSystemStat.getCount() - 1) / sqrt(outerTimeInSystemStat.getCount())
+            );
+        }
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/run/TestAnimations.java b/MV3302ClassCode/src/mv3302/run/TestAnimations.java
new file mode 100644
index 0000000000000000000000000000000000000000..46e18218344ef81193f1cdc63532d8944de75312
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/TestAnimations.java
@@ -0,0 +1,112 @@
+package mv3302.run;
+
+import java.awt.Color;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.List;
+import mv3302.SimpleCookieCutterMediator;
+import mv3302.SimpleMover;
+import mv3302.SimplePatrolMoverManager;
+import mv3302.SimpleReferee;
+import mv3302.sensor.AbstractSimpleSensor;
+import mv3302.sensor.SimpleCookieCutterSensor;
+import simkit.Schedule;
+import simkit.animate.SandboxFrame;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+import simkit.util.PropertyChangeFrame;
+
+/**
+ *
+ * @author ahbuss
+ */
+public class TestAnimations {
+
+    /**
+     * @param args the command line arguments
+     */
+    public static void main(String[] args) {
+        
+        SimpleMover mover1 = new SimpleMover(new Point2D.Double(-20.0, 0.0), 30.0);
+        AbstractSimpleSensor sensor1 = new SimpleCookieCutterSensor(mover1, 20.0);
+        Point2D[] moverPath1 = new Point2D[]{
+            new Point2D.Double(100.0, 0.0),
+            mover1.getInitialLocation()
+        };
+        SimplePatrolMoverManager moverManager1 = new SimplePatrolMoverManager(moverPath1, true);
+        
+        mover1.addSimEventListener(moverManager1);
+        moverManager1.addSimEventListener(mover1);
+        
+        SimpleMover mover2 = new SimpleMover(new Point2D.Double(50.0, 0.0), 40.0);
+        AbstractSimpleSensor sensor2 = new SimpleCookieCutterSensor(mover2, 30.0);
+        Point2D[] moverPath2 = new Point2D[] {
+            new Point2D.Double(-100.0, 0.0),
+            mover2.getInitialLocation()
+        };
+        SimplePatrolMoverManager moverManager2 = new SimplePatrolMoverManager(moverPath2, true);
+        mover2.addSimEventListener(moverManager2);
+        moverManager2.addSimEventListener(mover2);
+
+//        PropertyChangeListener propertyChangeFrame = new SimplePropertyDumper(true);
+        PropertyChangeFrame propertyChangeFrame = new PropertyChangeFrame();
+//        mover1.addPropertyChangeListener(propertyChangeFrame);
+//        moverManager1.addPropertyChangeListener(propertyChangeFrame);
+        sensor1.addPropertyChangeListener("detection", propertyChangeFrame);
+        sensor1.addPropertyChangeListener("undetection", propertyChangeFrame);
+        
+//        mover2.addPropertyChangeListener(propertyChangeFrame);
+//        moverManager2.addPropertyChangeListener(propertyChangeFrame);
+        sensor2.addPropertyChangeListener("detection", propertyChangeFrame);
+        sensor2.addPropertyChangeListener("undetection", propertyChangeFrame);
+//        
+        List<Mover> targets = new ArrayList<>();
+        targets.add(mover1);
+        targets.add(mover2);
+        
+        List<Sensor> sensors = new ArrayList<>();
+        sensors.add(sensor1);
+        sensors.add(sensor2);
+        
+        SimpleReferee referee = new SimpleReferee(sensors, targets);
+        
+        SimpleCookieCutterMediator mediator1 = new SimpleCookieCutterMediator();
+        referee.addSimEventListener(mediator1);
+        
+        System.out.println(mover1.paramString());
+        System.out.println(moverManager1);
+        System.out.println(sensor1.paramString());
+        
+        System.out.println(mover2.paramString());
+        System.out.println(moverManager2);
+        System.out.println(sensor2.paramString());
+        
+        System.out.println(referee);
+        
+        Schedule.setVerbose(false);
+        
+//        Schedule.stopOnEvent(5, "Detection", SimpleMover.class);
+        
+        
+        SandboxFrame sandboxFrame = new SandboxFrame("Simple Referee");
+        sandboxFrame.getSandbox().setOrigin(new Point2D.Double(200, 200));
+        sandboxFrame.getSandbox().setDrawAxes(true);
+        
+        sandboxFrame.addMover(mover1, Color.BLUE);
+        sandboxFrame.addSensor(sensor1, Color.RED);
+        sandboxFrame.addMover(mover2, Color.GREEN);
+        sandboxFrame.addSensor(sensor2, Color.ORANGE);
+        
+        sandboxFrame.setVisible(true);
+        
+        propertyChangeFrame.setLocation(sandboxFrame.getX() + sandboxFrame.getWidth(), sandboxFrame.getY());
+        propertyChangeFrame.setVisible(true);
+        Schedule.reset();
+        
+        Schedule.addIgnoreOnDump("Ping");
+
+//        Schedule.startSimulation();
+        
+    }
+    
+}
diff --git a/MV3302ClassCode/src/mv3302/run/testShipArrivalProcess.java b/MV3302ClassCode/src/mv3302/run/testShipArrivalProcess.java
new file mode 100644
index 0000000000000000000000000000000000000000..6d755c09298612c36d67f8f02774356a0d8360a5
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/run/testShipArrivalProcess.java
@@ -0,0 +1,83 @@
+/*
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
+ * Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Main.java to edit this template
+ */
+package mv3302.run;
+
+import mv3302.ShipArrivalProcess;
+import mv3302.TwoCranesBerth;
+import simkit.Adapter;
+import simkit.Schedule;
+import simkit.random.RandomVariate;
+import simkit.random.RandomVariateFactory;
+import simkit.stat.CollectionSizeTimeVaryingStats;
+import simkit.stat.SimpleStatsTally;
+
+/**
+ * A test class that simulates the arrival and unloading of ships at a two-crane
+ * berth. It initializes the required objects, listens to the events triggered
+ * by these objects, and collects statistical data during the simulation.
+ *
+ * @author dansl
+ */
+public class testShipArrivalProcess {
+
+    /**
+     * Runs the simulation of ship arrivals and unloading at a two-crane berth,
+     * and prints the collected statistical data at the end of the simulation.
+     */
+    public static void main(String[] args) {
+        RandomVariate interarrivalTimeGenerator = RandomVariateFactory.getInstance("Exponential", .7);
+        RandomVariate unloadingTimeGenerator = RandomVariateFactory.getInstance("Uniform", 0.5, 1.5);
+        ShipArrivalProcess shipArrivalProcess = new ShipArrivalProcess(interarrivalTimeGenerator, unloadingTimeGenerator);
+        System.out.println(shipArrivalProcess);
+
+        TwoCranesBerth twoCranesBerth = new TwoCranesBerth();
+        System.out.println(twoCranesBerth);
+
+        //        TwoCranesBerth will "hear" ShipArrivalProcess(Arrival) events
+        shipArrivalProcess.addSimEventListener(twoCranesBerth);
+
+//        The twoCranesBerth will "hear" the ShipArrival events of the
+//        first as Arrival events
+        Adapter adapter = new Adapter("ShipArrival", "Arrival");
+        adapter.connect(shipArrivalProcess, twoCranesBerth);
+
+//        This was used for debugging model
+//        SimplePropertyDumper simplePropertyDumper = new SimplePropertyDumper(true);
+//
+//        twoCranesBerth.addPropertyChangeListener(simplePropertyDumper);
+//        shipArrivalProcess.addPropertyChangeListener(simplePropertyDumper);
+        //        Tally statistics are computed in the same way by "listening" 
+        SimpleStatsTally timeInSystemStat = new SimpleStatsTally("timeInSystem");
+        twoCranesBerth.addPropertyChangeListener(timeInSystemStat);
+
+        SimpleStatsTally delayInQueueStat = new SimpleStatsTally("delayInQueue");
+        twoCranesBerth.addPropertyChangeListener(delayInQueueStat);
+
+        CollectionSizeTimeVaryingStats numberInBerthsStat = new CollectionSizeTimeVaryingStats("berths");
+        twoCranesBerth.addPropertyChangeListener(numberInBerthsStat);
+
+        CollectionSizeTimeVaryingStats numberInQueueStat = new CollectionSizeTimeVaryingStats("queue");
+        twoCranesBerth.addPropertyChangeListener(numberInQueueStat);
+        //        Was "true" when debugging model
+        Schedule.setVerbose(false);
+        double stopTime = 3650.0;
+        Schedule.stopAtTime(stopTime);
+
+//        Initialized & run 
+        Schedule.reset();
+        Schedule.startSimulation();
+
+        System.out.printf("%nSimulation ended at time %,.2f%n%n", Schedule.getSimTime());
+
+        System.out.printf("Number of Ships Arriving:\t %,d%n", shipArrivalProcess.getNumberArrivals());
+        System.out.printf("Number of Ships Unloaded:\t %,d%n", timeInSystemStat.getCount());
+        System.out.printf("Maximum # in Queue:\t\t %,.0f%n", numberInQueueStat.getMaxObs());
+        System.out.printf("Average # in Queue:\t\t %,.4f%n", numberInQueueStat.getMean());
+        System.out.printf("Average # Busy Berths:\t\t %,.4f%n", numberInBerthsStat.getMean());
+        System.out.printf("Average Time in System:\t\t %,.4f%n", timeInSystemStat.getMean());
+        System.out.printf("Average Delay in Queue:\t\t %,.4f%n", delayInQueueStat.getMean());
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java b/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..f2b133abfcb90dce5aafef7a009474552f5cbcb1
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/AbstractSimpleSensor.java
@@ -0,0 +1,221 @@
+package mv3302.sensor;
+
+import java.awt.geom.Point2D;
+import java.util.HashSet;
+import java.util.Set;
+import simkit.SimEntityBase;
+import simkit.smd.Mover;
+import simkit.smd.Sensor;
+
+/**
+ * An abstract class representing a simple sensor. It extends the SimEntityBase
+ * class and implements the Sensor interface. Provides common functionality for
+ * sensors that detect and track movers. Subclasses need to implement specific
+ * detection algorithms.
+ *
+ * @author dansl
+ */
+public abstract class AbstractSimpleSensor extends SimEntityBase implements Sensor {
+
+    private Mover mover;
+
+    private double maxRange;
+
+    protected Set<Mover> contacts;
+
+    /**
+     * Constructs a new AbstractSimpleSensor with an empty contacts set.
+     */
+    public AbstractSimpleSensor() {
+        contacts = new HashSet<>();
+    }
+
+    /**
+     * Constructs a new AbstractSimpleSensor with the specified mover and
+     * maximum range. The contacts set is initialized as an empty set.
+     *
+     * @param mover the mover associated with the sensor
+     * @param maxRange the maximum range of the sensor
+     */
+    public AbstractSimpleSensor(Mover mover, double maxRange) {
+        this();
+        setMover(mover);
+        setMaxRange(maxRange);
+    }
+
+    /**
+     * Resets the sensor to its initial state. Clears the contacts set.
+     */
+    @Override
+    public void reset() {
+        super.reset();
+        contacts.clear();
+    }
+
+    /**
+     * Runs the sensor and fires a property change event for the contacts set.
+     */
+    public void doRun() {
+        firePropertyChange("contacts", getContacts());
+    }
+
+    /**
+     * Performs detection of a target mover. Adds the target mover to the
+     * contacts set and fires property change events for contacts and detection.
+     *
+     * @param target the mover to be detected
+     */
+    public void doDetection(Mover target) {
+        Set<Mover> oldContacts = getContacts();
+        contacts.add(target);
+        firePropertyChange("contacts", oldContacts, getContacts());
+
+        firePropertyChange("detection", target);
+    }
+
+    /**
+     * Removes a target mover from the contacts set. Fires property change
+     * events for contacts and undetection.
+     *
+     * @param target the mover to be undetected
+     */
+    public void doUndetection(Mover target) {
+        Set<Mover> oldContacts = getContacts();
+        contacts.remove(target);
+        firePropertyChange("contacts", oldContacts, getContacts());
+
+        firePropertyChange("undetection", target);
+    }
+
+    /**
+     * Initiates the start move action for the specified mover. Delays the
+     * action for the current simulation time.
+     *
+     * @param mover the mover to start moving
+     */
+    public void doStartMove(Mover mover) {
+        waitDelay("StartMove", 0.0, this);
+    }
+
+    /**
+     * Initiates the stop action for the specified mover. Delays the action for
+     * the current simulation time.
+     *
+     * @param mover the mover to stop
+     */
+    public void doStop(Mover mover) {
+        waitDelay("Stop", 0.0, this);
+    }
+
+    /**
+     * Initiates the stop action for the specified mover. Delays the action for
+     * the current simulation time.
+     *
+     * @param mover the mover to stop
+     */
+    public void setMover(Mover mover) {
+        this.mover = mover;
+        this.mover.addSimEventListener(this);
+    }
+
+    /**
+     * Returns the maximum range of the sensor.
+     *
+     * @return the maxRange
+     */
+    @Override
+    public double getMaxRange() {
+        return maxRange;
+    }
+
+    /**
+     * Sets the maximum range of the sensor.
+     *
+     * @param maxRange the maxRange to set
+     */
+    public void setMaxRange(double maxRange) {
+        if (maxRange < 0.0) {
+            throw new IllegalArgumentException("maxRange must be ≥ 0.0: " + maxRange);
+        }
+        this.maxRange = maxRange;
+    }
+
+    /**
+     * Sets the contacts of the sensor.
+     *
+     * @return the contacts
+     */
+    @Override
+    public Set<Mover> getContacts() {
+        return new HashSet<>(contacts);
+    }
+
+    /**
+     * Returns the mover associated with the sensor.
+     *
+     * @return the mover
+     */
+    @Override
+    public Mover getMover() {
+        return mover;
+    }
+
+    /**
+     * Returns current location the mover associated with the sensor.
+     *
+     * @return the mover.currentLocation
+     */
+    @Override
+    public Point2D getCurrentLocation() {
+        return mover.getCurrentLocation();
+    }
+
+    /**
+     * Returns velocity of the mover associated with the sensor.
+     *
+     * @return the movers velocity
+     */
+    @Override
+    public Point2D getVelocity() {
+        return mover.getVelocity();
+    }
+
+    /**
+     * empty method for implementation
+     */
+    @Override
+    public void doStartMove(Sensor sensor) {
+    }
+
+    /**
+     * empty method for implementation
+     */
+    @Override
+    public void doStop(Sensor sensor) {
+    }
+
+    /**
+     * Returns a string representation of the AbstractSimpleSensor object. This
+     * method is overridden from the superclass to provide a customized string
+     * representation.
+     *
+     * @return a string representation of the AbstractSimpleSensor object
+     */
+    public String paramString() {
+        return super.toString();
+    }
+
+    /**
+     * Returns a string representation of the AbstractSimpleSensor object. The
+     * string format includes the name, current location, velocity, and maximum
+     * range of the sensor.
+     *
+     * @return a string representation of the AbstractSimpleSensor object
+     */
+    @Override
+    public String toString() {
+        return String.format("%s %s %s %,.4f", getName(), mover.getCurrentLocation(), mover.getVelocity(),
+                getMaxRange());
+    }
+
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/Sensor.java b/MV3302ClassCode/src/mv3302/sensor/Sensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..8e6b57b163a90d248c4181cf4b4c5947c7516139
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/Sensor.java
@@ -0,0 +1,24 @@
+package mv3302.sensor;
+
+import java.awt.geom.Point2D;
+import java.util.Set;
+import simkit.SimEntity;
+import simkit.smd.Mover;
+
+/**
+ *The Sensor interface represents a sensor entity in a simulation. It extends the SimEntity interface.
+A sensor can provide information about its current location, velocity, and maximum range.
+It can also start and stop moving, retrieve the mover associated with it, and get a set of contacts.
+ * @author dansl
+ */
+interface Sensor extends SimEntity {
+
+    public Point2D getCurrentLocation();
+    public Point2D getVelocity();
+    public double getMaxRange();
+    public void doStartMove(Mover mover);
+    public void doStop(Mover mover);
+    public Mover getMover();
+    public Set<Mover> getContacts();
+
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..c0ca9377f557f1014edcacd46cf3855fd1150409
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantRateSensor.java
@@ -0,0 +1,59 @@
+package mv3302.sensor;
+
+import simkit.smd.Mover;
+
+/**
+ * A simple constant rate sensor that detects objects within a maximum range
+ * based on a mean time to detect. Inherits from AbstractSimpleSensor.
+ */
+public final class SimpleConstantRateSensor extends AbstractSimpleSensor {
+
+    private double meanTimeToDetect;
+
+    /**
+     * Constructs a SimpleConstantRateSensor object with default values.
+     */
+    public SimpleConstantRateSensor() {
+        super();
+    }
+
+    /**
+     *
+     * Constructs a SimpleConstantRateSensor object with the specified mover,
+     * maximum range, and mean time to detect.
+     *
+     * @param mover the mover associated with the sensor
+     * @param maxRange the maximum range of the sensor
+     * @param meanTimeToDetect the mean time taken by the sensor to detect an
+     * object
+     */
+    public SimpleConstantRateSensor(Mover mover, double maxRange, double meanTimeToDetect) {
+        super(mover, maxRange);
+        setMeanTimeToDetect(meanTimeToDetect);
+    }
+
+    /**
+     *
+     * Returns the mean time to detect an object.
+     *
+     * @return the mean time to detect an object
+     */
+    public double getMeanTimeToDetect() {
+        return meanTimeToDetect;
+    }
+
+    /**
+     *
+     * Sets the mean time to detect an object.
+     *
+     * @param meanTimeToDetect the mean time to detect an object
+     * @throws IllegalArgumentException if the meanTimeToDetect value is less
+     * than 0.0
+     */
+    public void setMeanTimeToDetect(double meanTimeToDetect) {
+        if (meanTimeToDetect < 0.0) {
+            throw new IllegalArgumentException("meanTimeToDetect must be >= 0.0: " + meanTimeToDetect);
+        }
+        this.meanTimeToDetect = meanTimeToDetect;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..363ed14c0a436a4b5b8292111c61c81d5094a414
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/SimpleConstantTimeSensor.java
@@ -0,0 +1,57 @@
+package mv3302.sensor;
+
+import simkit.smd.Mover;
+
+/**
+ * A simple constant time sensor that detects objects in a given time frame. It
+ * extends the AbstractSimpleSensor class.
+ */
+public final class SimpleConstantTimeSensor extends AbstractSimpleSensor {
+
+    protected double timeToDetect;
+
+    /**
+     * Creates a new instance of SimpleConstantTimeSensor with default values.
+     */
+    public SimpleConstantTimeSensor() {
+        super();
+    }
+
+    /**
+     * Creates a new instance of SimpleConstantTimeSensor with the specified
+     * parameters.
+     *
+     * @param mover the mover object associated with the sensor
+     * @param maxRange the maximum range of the sensor
+     * @param timeToDetect the time taken by the sensor to detect an object
+     */
+    public SimpleConstantTimeSensor(Mover mover, double maxRange, double timeToDetect) {
+        super(mover, maxRange);
+        setTimeToDetect(timeToDetect);
+    }
+
+    /**
+     *
+     * Returns the time taken by the sensor to detect an object.
+     *
+     * @return the time to detect an object
+     */
+    public double getTimeToDetect() {
+        return timeToDetect;
+    }
+
+    /**
+     *
+     * Sets the time taken by the sensor to detect an object.
+     *
+     * @param timeToDetect the time to detect an object (must be >= 0.0)
+     * @throws IllegalArgumentException if the provided timeToDetect is less
+     * than 0.0
+     */
+    public void setTimeToDetect(double timeToDetect) {
+        if (timeToDetect < 0.0) {
+            throw new IllegalArgumentException("timeToDetect must be >= 0.0: " + timeToDetect);
+        }
+        this.timeToDetect = timeToDetect;
+    }
+}
diff --git a/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java b/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java
new file mode 100644
index 0000000000000000000000000000000000000000..2ff1765f07d1695eff31345305828a1d49c911c5
--- /dev/null
+++ b/MV3302ClassCode/src/mv3302/sensor/SimpleCookieCutterSensor.java
@@ -0,0 +1,30 @@
+package mv3302.sensor;
+
+import simkit.smd.Mover;
+
+/**
+ *
+ * A simple implementation of a cookie cutter sensor for detecting objects using
+ * a mover and a maximum range. Extends the AbstractSimpleSensor class.
+ */
+public class SimpleCookieCutterSensor extends AbstractSimpleSensor {
+
+    /**
+     * Constructs a new instance of SimpleCookieCutterSensor with default
+     * values.
+     */
+    public SimpleCookieCutterSensor() {
+        super();
+    }
+
+    /**
+     * Constructs a new instance of SimpleCookieCutterSensor with the specified
+     * mover and maximum range.
+     *
+     * @param mover the mover object associated with the sensor
+     * @param maxRange the maximum range at which the sensor can detect objects
+     */
+    public SimpleCookieCutterSensor(Mover mover, double maxRange) {
+        super(mover, maxRange);
+    }
+}
diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/PduCaptureLogFredrickson.dislog b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/PduCaptureLogFredrickson.dislog
new file mode 100644
index 0000000000000000000000000000000000000000..9ecd8e9263f3a7b12d638c215c304b58ae63cd92
--- /dev/null
+++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/PduCaptureLogFredrickson.dislog
@@ -0,0 +1,54 @@
+# Start, ENCODING_PLAINTEXT, [PduRecorder] 20230605_132110, DIS capture file, .\pduLog\PduCaptureLog4.dislog
+# Timestamp(8 bytes),ProtocolVersion,CompatibilityVersion,ExerciseID,PduType,PduStatus,HeaderLength,PduLength,then PDU-specific data
+# =============================================
+# DisPduType 11 CREATE_ENTITY, Session time 13:21:10.9, session duration 00:00:00.0, Pdu timestamp 1516340589 05:43:09.0, simulation stream interval 0 00:00:00.0
+0,0,43,-72,102,70,23,29,7,4,11,5,90,97,-123,109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+# DisPduType 11 CREATE_ENTITY, Session time 13:21:11.0, session duration 00:00:00.0, Pdu timestamp 1516340589 05:43:09.0, simulation stream interval 0 00:00:00.0
+0,0,0,0,0,-95,108,56,7,4,11,5,90,97,-123,109,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+# DisPduType 22 COMMENT, Session time 13:21:11.0, session duration 00:00:00.0, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,0,-86,-86,-96,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-81,-46,0,0,1,64,83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,115,116,101,112,32,100,117,114,97,116,105,111,110,32,49,46,48,32,115,101,99,111,110,100,115
+# DisPduType 22 COMMENT, Session time 13:21:11.0, session duration 00:00:00.1, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,6,111,9,4,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,-53,32,0,0,2,16,83,105,109,117,108,97,116,105,111,110,32,116,105,109,101,32,48,46,48,32,97,116,32,76,111,99,97,108,68,97,116,101,84,105,109,101,32,50,48,50,51,45,48,54,45,48,53,84,49,51,58,50,49,58,49,49,46,48,57,53,57,48,53,50,48,48,0,0,0,0,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:12.2, session duration 00:00:01.2, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,72,-31,-56,48,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,-16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0
+# DisPduType 02 FIRE, Session time 13:21:12.3, session duration 00:00:01.3, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,79,5,-76,-80,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0
+# DisPduType 22 COMMENT, Session time 13:21:12.4, session duration 00:00:01.4, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,85,16,-79,52,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,49,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:12.5, session duration 00:00:01.5, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,91,-46,77,-84,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:13.6, session duration 00:00:02.6, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,-98,-121,6,76,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0
+# DisPduType 02 FIRE, Session time 13:21:13.7, session duration 00:00:02.7, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,-92,-102,39,48,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0
+# DisPduType 22 COMMENT, Session time 13:21:13.8, session duration 00:00:02.8, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,-86,-56,78,112,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,50,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:13.9, session duration 00:00:02.9, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,-79,114,-87,-56,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:15.0, session duration 00:00:04.0, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,-12,93,58,100,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0
+# DisPduType 02 FIRE, Session time 13:21:15.1, session duration 00:00:04.2, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,0,-6,-24,-10,-84,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0
+# DisPduType 22 COMMENT, Session time 13:21:15.3, session duration 00:00:04.3, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,1,-105,-55,-60,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,51,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:15.4, session duration 00:00:04.4, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,8,73,-44,-80,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:16.5, session duration 00:00:05.5, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,75,11,-112,44,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0
+# DisPduType 02 FIRE, Session time 13:21:16.6, session duration 00:00:05.6, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,81,127,92,-72,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0
+# DisPduType 22 COMMENT, Session time 13:21:16.7, session duration 00:00:05.7, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,88,22,2,-64,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,52,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:16.8, session duration 00:00:05.8, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,94,-98,-99,20,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:17.9, session duration 00:00:06.9, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,-96,-78,-80,-76,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,3,1,0,1,2,0,-31,23,2,1,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,20,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,69,110,116,105,116,121,32,35,53,51,0,0,0,0
+# DisPduType 02 FIRE, Session time 13:21:18.0, session duration 00:00:07.1, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,-89,58,31,108,7,1,2,2,0,0,0,0,0,96,40,0,0,2,0,3,0,0,0,2,0,3,0,0,0,2,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,122,0,0
+# DisPduType 22 COMMENT, Session time 13:21:18.2, session duration 00:00:07.2, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,-83,-30,23,112,7,1,22,5,0,0,0,0,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,3,-87,-72,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,3,-87,-72,0,0,0,-80,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,108,111,111,112,32,53,0,0
+# DisPduType 01 ENTITY_STATE, Session time 13:21:18.3, session duration 00:00:07.3, Pdu timestamp 0 00:00:00.0, simulation stream interval -1516340589 18:16:51.0
+0,0,0,1,-76,-59,61,16,7,1,1,1,0,0,0,0,0,-112,40,0,0,1,0,2,0,4,2,0,1,3,0,-51,62,2,2,0,0,0,0,-31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,69,110,116,105,116,121,32,35,50,0,0,0,0
+# DisPduType 22 COMMENT, Session time 13:21:18.4, session duration 00:00:07.4, Pdu timestamp 2556 00:42:36.0, simulation stream interval -1516338033 18:59:27.0
+0,0,0,1,-70,-62,-93,116,7,1,22,5,0,0,9,-4,0,32,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,9,90,-90,0,0,0,-8,77,86,51,53,48,48,32,69,120,97,109,112,108,101,83,105,109,117,108,97,116,105,111,110,80,114,111,103,114,97,109,0,0,9,90,-90,0,0,1,48,114,117,110,83,105,109,117,108,97,116,105,111,110,40,41,32,99,111,109,112,108,101,116,101,100,32,115,117,99,99,101,115,115,102,117,108,108,121,0,0
+# Finish, ENCODING_PLAINTEXT, [PduRecorder] 20230605_132120, DIS capture file, .\pduLog\PduCaptureLog4.dislog
diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/README.md b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..4fb1b94685ed87fed1d0d3c13414db4e528d0421
--- /dev/null
+++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/README.md
@@ -0,0 +1,3 @@
+## Homework 3: Example Simulation Recording using OpenDIS Network Streams
+
+// (INSERT DIFFERENCES HERE)
\ No newline at end of file
diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/package-info.java b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/package-info.java
index 2707e4a293289fe1c51eb7a3e608d605727c5a1f..7729ccd90f91ecb22dc986ca35c3d1f2e3d0463b 100644
--- a/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/package-info.java
+++ b/assignments/src/MV3500Cohort2023MarchJune/homework3/Fredrickson/package-info.java
@@ -1,5 +1,5 @@
 /**
- * Final project assignments supporting the NPS MOVES MV3500 Networked Graphics course.
+ * Assignment 3 - Example Simulation Program.
  * 
  * @see <a href="https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/tree/master/assignments">networkedGraphicsMV3500 assignments</a>
  * @see java.lang.Package
diff --git a/assignments/src/MV3500Cohort2023MarchJune/homework4/README.md b/assignments/src/MV3500Cohort2023MarchJune/homework4/README.md
index 587911d33c740f7341226132a1c7c6fa78a94cfb..8b37870df619103d102fe351df69f9ba77d8e5a9 100644
--- a/assignments/src/MV3500Cohort2023MarchJune/homework4/README.md
+++ b/assignments/src/MV3500Cohort2023MarchJune/homework4/README.md
@@ -18,3 +18,8 @@ Deliverables:
 
 Please see the [README.md](../../../README.md) in the parent
 [assignments](../../../../assignments) directory for detailed instructions.
+
+
+In class Discussion: 
+    How might PDUs look for a drone swarm?  
+        Two perspectives may be necessary.  The first is that each drone is it's own entity, requiring it's own PDU.  The second is that the swarm itself is also an entity, and should have a PDU that reflects the group as well.