Using visual studio 2022, a C# windows form application, and your DoubleLinkedClass and DoubleLinkedNode classes from project 5, implement a DequeueClass, a StackClass, and a QueueClass. Do not use any arrays, lists, dictionaries, or other built in data structures, only instances of your linkedLists classes from project 5. The dequeue class needs to contain a reference to an instance of your DoubleLinkedList class, with the QueueClass and StackClass inheriting from the Dequeue class. Your Stack and Queue pop and push need to be one-line calls to the Dequeue popLeft, pushLeft, popRight, pushRight. Do not copy the code from the dequeue class to implement the Stack and Queue. DoubleLinkedClasses From2263Project5 internal class DoubleLinkedList<T> { public DoubleLinkedListNode<T> firstNode = null; public DoubleLinkedListNode<T> lastNode = null; public DoubleLinkedListNode<T> currentNode = null; public int nodeNumber = 0; public DoubleLinkedList() { } // creates first node in list with firstValue public DoubleLinkedList(T firstValue) { firstNode = new DoubleLinkedListNode<T>(firstValue); lastNode = firstNode; currentNode = firstNode; nodeNumber = 1; } public DoubleLinkedListNode<T> GetCurrentNode() { return currentNode; } public void InsertFirst(T value) { DoubleLinkedListNode<T> newNode = new DoubleLinkedListNode<T>(value); if (firstNode == null) { firstNode = newNode; lastNode = firstNode; currentNode = firstNode; } else { newNode.next = firstNode; firstNode.previous = newNode; firstNode = newNode; currentNode = firstNode; } nodeNumber++; } public void InsertBeforeFirst(T value) { if (firstNode == null) { InsertFirst(value); return; } DoubleLinkedListNode<T> newNode = new DoubleLinkedListNode<T>(value); newNode.next = firstNode; firstNode.previous = newNode; firstNode = newNode; nodeNumber++; } public void InsertAfterLast(T value) { if (lastNode == null) { InsertFirst(value); return; } DoubleLinkedListNode<T> newNode = new DoubleLinkedListNode<T>(value); lastNode.next = newNode; newNode.previous = lastNode; lastNode = newNode; currentNode = lastNode; nodeNumber++; } public void InsertAfterCurrent(T value) { if (currentNode == null) { InsertFirst(value); return; } DoubleLinkedListNode<T> newNode = new DoubleLinkedListNode<T>(value); newNode.next = currentNode.next; newNode.previous = currentNode; if (currentNode.next != null) { currentNode.next.previous = newNode; } currentNode.next = newNode; currentNode = newNode; if (lastNode == currentNode.previous) { lastNode = currentNode; } nodeNumber++; } public int NumberOfNodesInList() { return nodeNumber; } public void DeleteFirst() { if (firstNode == null) { return; } if (firstNode.next == null) { firstNode = null; lastNode = null; currentNode = null; } else { firstNode = firstNode.next; firstNode.previous = null; currentNode = firstNode; } nodeNumber--; } public void DeleteLast() { if (lastNode == null) { return; } if (lastNode.previous == null) { firstNode = null; lastNode = null; currentNode = null.