
  PROCEDURE [INLINE] clp$delete_variable_from_tree
    (    hashed_name: clt$variable_name;
         hash: clt$variable_name_hash;
         allowed_data_classes: clt$internal_variable_classes;
     VAR variables {input, output}: clt$variables;
     VAR variable_descriptor: ^clt$variable_descriptor);

?? PUSH (LISTEXT := ON) ??

    VAR
      access_to_be_deleted: ^clt$variable_access,
      current_access: ^^clt$variable_access,
      replacement: ^^clt$variable_access;


    variable_descriptor := NIL;
    current_access := ^variables.hash_groups [hash].root;

  /locate_variable/
    WHILE current_access^ <> NIL DO
      IF hashed_name < current_access^^.hashed_name THEN
        current_access := ^current_access^^.left_search_tree;
      ELSEIF hashed_name > current_access^^.hashed_name THEN
        current_access := ^current_access^^.right_search_tree;
      ELSE
        EXIT /locate_variable/;
      IFEND;
    WHILEND /locate_variable/;

    IF (current_access^ = NIL) OR  NOT (current_access^^.info.class IN allowed_data_classes) THEN
      RETURN;
    IFEND;

    access_to_be_deleted := current_access^;
    CASE current_access^^.info.class OF
    = clc$env_variable, clc$lib_variable, clc$pushed_variable =
      variables.hash_groups [hash].environment_variables_in_group :=
            variables.hash_groups [hash].environment_variables_in_group - 1;
    ELSE
      variables.hash_groups [hash].procedure_variables_in_group :=
            variables.hash_groups [hash].procedure_variables_in_group - 1;
    CASEND;
    variable_descriptor := current_access^^.info.descriptor;

    IF current_access^^.backward_thread <> NIL THEN
      current_access^^.backward_thread^.forward_thread := current_access^^.forward_thread;
    ELSE
      variables.thread := current_access^^.forward_thread;
    IFEND;
    IF current_access^^.forward_thread <> NIL THEN
      current_access^^.forward_thread^.backward_thread := current_access^^.backward_thread;
    IFEND;

{ Remove variable from the search tree.

    IF current_access^^.left_search_tree = NIL THEN
      current_access^ := current_access^^.right_search_tree;
    ELSEIF current_access^^.right_search_tree = NIL THEN
      current_access^ := current_access^^.left_search_tree;
    ELSE

{ Find largest member of variable's left search tree and use it to replace the deleted variable in the tree.

      replacement := ^current_access^^.left_search_tree;
      WHILE replacement^^.right_search_tree <> NIL DO
        replacement := ^replacement^^.right_search_tree;
      WHILEND;
      current_access^ := replacement^;
      replacement^ := replacement^^.left_search_tree;
      current_access^^.right_search_tree := access_to_be_deleted^.right_search_tree;
      current_access^^.left_search_tree := access_to_be_deleted^.left_search_tree;
    IFEND;

    access_to_be_deleted^.info.assignment_counter := 0;
    access_to_be_deleted^.info.descriptor := NIL;
    FREE access_to_be_deleted IN osv$task_shared_heap^;

  PROCEND clp$delete_variable_from_tree;

*copyc clt$internal_variable_classes
*copyc clt$variables
*copyc clt$variable_access
*copyc clt$variable_descriptor
*copyc clt$variable_name
*copyc clt$variable_name_hash
?? POP ??
