diff --git a/FabAccessAPI/Machines.cs b/FabAccessAPI/Machines.cs
new file mode 100644
index 0000000..d5d2247
--- /dev/null
+++ b/FabAccessAPI/Machines.cs
@@ -0,0 +1,176 @@
+using FabAccessAPI.Schema;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace FabAccessAPI {
+ ///
+ /// Wraps a capability for accessing the Machines subsystem of BFFH
+ ///
+ class Machines {
+ private IMachines _machinesCap;
+
+ ///
+ /// Constructs the Wrapper Class from a given capability.
+ ///
+ /// The capability that should be wrapped.
+ public Machines(IMachines machinesCap) {
+ _machinesCap = machinesCap;
+ }
+
+ ///
+ /// List of all machines that BFFH knows about the user has been granted at least read access on
+ ///
+ /// ReadOnlyList of available Machines
+ public async Task> ListMachines() {
+ return (await _machinesCap.ListMachines().ConfigureAwait(false)).Select(x => new Machine(x)) as IReadOnlyList;
+ }
+
+ ///
+ /// Access a particular machine by known UUID. This may fail for two reasons:
+ /// The user has not been granted access to know the machine exists or the machine does in fact not exist.
+ /// In both cases the `machine` result will be a NULL-pointer
+ ///
+ /// UUID of the Machine
+ /// The Machine we requested
+ public async Task GetMachine(UUID uuid) {
+ var mach = (await _machinesCap.GetMachine(uuid).ConfigureAwait(false)).Item1;
+ if (mach == null) {
+ //TODO: Throw a more specific exception!
+ throw new Exception();
+ }
+ return new Machine(mach);
+ }
+ }
+
+ ///
+ /// A machine. This represents a machine as BFFH thinks about it which may mean
+ ///several machines or just part of a machine in the real world.
+ ///By itself this struct is completely useless since it contains only the information
+ ///that the machine exists the user is allowed to know about that fact. For all further
+ ///information the user has to call the contained capabilities which depending on the
+ ///access level may not be set. For example an admin will have every capability here
+ ///set but a simple user may only have `read` and `write` set while some users may not
+ /// even have `read` set and are unable to even see if the machine is currently in use.
+ ///
+ class Machine {
+ private Schema.Machine _machine;
+
+ ///
+ /// Constructs the Wrapper Class from a given capability
+ ///
+ /// The capability that should be wrapped.
+ public Machine(Schema.Machine machine) {
+ _machine = machine;
+ }
+
+ // read operations
+
+ ///
+ /// Get the MInfo Struct for the Machine.
+ /// This contains everything BFFH knows about the Machine.
+ ///
+ ///
+ /// The MInfo Struct describing the Machine
+ public async Task GetMInfo() {
+ var readCap = _machine.Read;
+ if (readCap == null) {
+ throw new UnauthorizedException();
+ }
+
+ return (await _machine.Read.Info().ConfigureAwait(false)).Item1;
+ }
+
+ //write operations
+
+ ///
+ /// Try to use a machine. Throws a UnauthorizedException if the user does not have the required
+ /// permissions to use this machine.
+ ///
+ /// Use the Ret() Method of the returned Object to return the machine
+ ///
+ ///
+ /// Capability to give back the machine
+ public Task Use() {
+ var writeCap = _machine.Write;
+ if (writeCap == null) {
+ throw new UnauthorizedException();
+ }
+
+ return writeCap.Use();
+ }
+
+
+ // public void GiveBack(Schema.Machine.WriteInterface.IGiveBack cap) {
+ // cap.Ret();
+ // }
+
+ //manage operations
+
+ ///
+ /// After a machine has been used by an user with low enough permissions it's
+ /// in the 'toCheck' state. This call then allows more priviledged users to
+ /// "check" the machine and move it to the `free` state.
+ ///
+ /// Calling this method signifies that the machine was checked and in an acceptable state.
+ ///
+ public async void MarkOk() {
+ var manageCap = _machine.Manage;
+ if (manageCap == null) {
+ throw new UnauthorizedException();
+ }
+ // TODO: Do we really want to check this here?
+ if ((await GetMInfo().ConfigureAwait(false)).State == State.toCheck) {
+ await _machine.Manage.Ok().ConfigureAwait(false);
+ }
+ }
+
+ ///
+ /// After a machine has been used by an user with low enough permissions it's
+ /// in the 'toCheck' state. This call then allows more priviledged users to
+ /// "check" the machine and move it to the `free` state.
+ ///
+ /// Calling this method signifies that the machine was checked and in an unacceptable state.
+ /// It will most likely be marked as `blocked` and the previous user will somehow be informed.
+ ///
+ public async void MarkNotOk() {
+ var manageCap = _machine.Manage;
+ if (manageCap == null) {
+ throw new UnauthorizedException();
+ }
+ // TODO: Do we really want to check this here?
+ if ((await GetMInfo().ConfigureAwait(false)).State == State.toCheck) {
+ await _machine.Manage.NotOk().ConfigureAwait(false);
+ }
+ }
+
+ //administrative operations
+
+ ///
+ /// Forcefully set a machine state.
+ ///
+ /// The desired machine state.
+ public async void ForceSetState(State state) {
+ var adminCap = _machine.Admin;
+ if (adminCap == null) {
+ throw new UnauthorizedException();
+ }
+
+ await adminCap.ForceSetState(state).ConfigureAwait(false);
+ }
+
+ ///
+ /// Set the given user as current responsible
+ ///
+ /// The user
+ public async void ForceSetUser(String user) {
+ var adminCap = _machine.Admin;
+ if (adminCap == null) {
+ throw new UnauthorizedException();
+ }
+
+ await adminCap.ForceSetUser(user).ConfigureAwait(false);
+ }
+ }
+}