(define (make-bintree key value left right)
  (define (get-key) key)
  (define (get-value) value)
  (define (get-left) left)
  (define (get-right) right)
  (define (set-left! node) (set! left node))
  (define (set-right! node) (set! right node))
  (define (set-value! v) (set! value v))
  (define (dispatch m)
    (cond ((eq? m 'k) get-key)
          ((eq? m 'v) get-value)
          ((eq? m 'l) get-left)
          ((eq? m 'r) get-right)
          ((eq? m 'sl!) set-left!)
          ((eq? m 'sr!) set-right!)
          ((eq? m 'sv!) set-value!)))
  dispatch)

(define tet 'gloriosky)
(define (empty-tree? t) (eq? t tet))

; 1. Write SELECTORS key, value, left, and right
(define (key bst) ((bst 'k)))
; We should test key before going further. We should really test
; every procedure we write before going further.  Here's a simple
; test example:
(define t (make-bintree 35 'otter tet tet))
(key t)  ; should return 35; if it doesn't, fix it

(define (value bst) ((bst 'v)))
(define (left bst) ((bst 'l)))
(define (right bst) ((bst 'r)))

; Write MUTATORS set-left!, set-right!, and set-value!
(define (set-left! k v t) ((t 'sl!) (make-bintree k v tet tet)))
(define (set-right! k v t) ((t 'sr!) (make-bintree k v tet tet)))
(define (set-value! v t) ((t 'sv!) v))

; Write MUTATOR insert! that takes a key, value, and binary search tree and does one of two things:
; If the key is in the tree, change the value for the node containing the key
;   otherwise put a new node into the correct place in the tree containing the key and value

(define (insert! k v t)
  (cond ((equal? k (key t)) (set-value! v t))
        ((< k (key t))
         (if (empty-tree? (left t)) (set-left! k v t) (insert! k v (left t))))
        (else
         (if (empty-tree? (right t)) (set-right! k v t) (insert! k v (right t))))))

(define bst (make-bintree 10 'cow tet tet))
(insert! 4 'fish bst)
(insert! 17 'arugula bst)
(insert! 13 'pepsi bst)

; Write the function inorder that returns a list of all of the key-value pairs in a binary search tree.
; Use cons to present the data as pairs.
(define (inorder t)
  (cond ((empty-tree? t) '())  ; Range of inorder is a list; this is the smallest list
        (else (append
               (inorder (left t))
               (list (cons (key t) (value t)))
               (inorder (right t))))))