code: def read_updated_trees(paths, debug_sentence=None):
      # original version with more errors
      # con_filename = os.path.join(con_directory, "2011-12-20", "Archive", "VIT_newconstsynt.txt")
      # this is the April 2022 version
      # con_filename = os.path.join(con_directory, "VIT_newconstsynt.txt")
      # the most recent update from ELRA may look like this?
      # it's what we got, at least
      # con_filename = os.path.join(con_directory, "italian", "VITwritten", "VITconstsyntNumb")
  
      # needs at least UD 2.11 or this will not work
      con_directory = paths["CONSTITUENCY_BASE"]
      ud_directory = os.path.join(paths["UDBASE"], "UD_Italian-VIT")
  
      con_filename = os.path.join(
          con_directory,
          "italian",
          "it_vit",
          "VITwritten",
          "VITconstsyntNumb",
      )
      ud_vit_train = os.path.join(
          ud_directory, "it_vit-ud-train.conllu"
      )
      ud_vit_dev = os.path.join(ud_directory, "it_vit-ud-dev.conllu")
      ud_vit_test = os.path.join(ud_directory, "it_vit-ud-test.conllu")
  
      print("Reading UD train/dev/test")
      ud_train_data = CoNLL.conll2doc(input_file=ud_vit_train)
      ud_dev_data = CoNLL.conll2doc(input_file=ud_vit_dev)
      ud_test_data = CoNLL.conll2doc(input_file=ud_vit_test)
  
      ud_vit_train_map = {
          DEP_ID_FUNC(x): x for x in ud_train_data.sentences
      }
      ud_vit_dev_map = {
          DEP_ID_FUNC(x): x for x in ud_dev_data.sentences
      }
      ud_vit_test_map = {
          DEP_ID_FUNC(x): x for x in ud_test_data.sentences
      }
  
      print("Getting ADP/DET expansions from UD data")
      mwt_map = get_mwt(ud_train_data, ud_dev_data, ud_test_data)
  
      con_sentences = read_constituency_file(con_filename)
      num_discarded = 0
      con_tree_map = {}
      for idx, sentence in enumerate(
          tqdm(con_sentences, postfix="Processing")
      ):
          try:
              tree = raw_tree(sentence[1])
              if sentence[0].startswith("#ID="):
                  tree_id = sentence[0].split("=")[-1]
              else:
                  tree_id = sentence[0].split("#")[-1]
              # don't care about the raw text?
              con_tree_map[tree_id] = tree
          except UnclosedTreeError as e:
              num_discarded = num_discarded + 1
              print(
                  "Discarding {} because of reading error:\n  {}: {}\n  {}".format(
                      sentence[0], type(e), e, sentence[1]
                  )
              )
          except ExtraCloseTreeError as e:
              num_discarded = num_discarded + 1
              print(
                  "Discarding {} because of reading error:\n  {}: {}\n  {}".format(
                      sentence[0], type(e), e, sentence[1]
                  )
              )
          except ValueError as e:
              print(
                  "Discarding {} because of reading error:\n  {}: {}\n  {}".format(
                      sentence[0], type(e), e, sentence[1]
                  )
              )
              num_discarded = num_discarded + 1
              # raise ValueError("Could not process line %d" % idx) from e
  
      print(
          "Discarded %d trees.  Have %d trees left"
          % (num_discarded, len(con_tree_map))
      )
      if num_discarded > 0:
          raise ValueError(
              "Oops!  We thought all of the VIT trees were properly bracketed now"
          )
      con_vit_ngrams = build_ngrams(
          con_tree_map.items(),
          lambda x: CON_PROCESS_FUNC(x[1]),
          lambda x: x[0],
      )
  
      # TODO: match more sentences.  some are probably missing because of MWT
      train_ids = match_sentences(
          con_tree_map,
          con_vit_ngrams,
          ud_train_data.sentences,
          "train",
          debug_sentence,
      )
      dev_ids = match_sentences(
          con_tree_map,
          con_vit_ngrams,
          ud_dev_data.sentences,
          "dev",
          debug_sentence,
      )
      test_ids = match_sentences(
          con_tree_map,
          con_vit_ngrams,
          ud_test_data.sentences,
          "test",
          debug_sentence,
      )
      print(
          "Remaining total trees: %d"
          % (len(train_ids) + len(dev_ids) + len(test_ids))
      )
      print(
          "  {} train {} dev {} test".format(
              len(train_ids), len(dev_ids), len(test_ids)
          )
      )
      print("Updating trees with MWT and newer tokens from UD...")
  
      # the moveprune feature requires a new corenlp release after 4.4.0
      with tsurgeon.Tsurgeon(
          classpath="$CLASSPATH"
      ) as tsurgeon_processor:
          train_trees = extract_updated_dataset(
              con_tree_map,
              ud_vit_train_map,
              train_ids,
              mwt_map,
              tsurgeon_processor,
          )
          dev_trees = extract_updated_dataset(
              con_tree_map,
              ud_vit_dev_map,
              dev_ids,
              mwt_map,
              tsurgeon_processor,
          )
          test_trees = extract_updated_dataset(
              con_tree_map,
              ud_vit_test_map,
              test_ids,
              mwt_map,
              tsurgeon_processor,
          )
  
      return train_trees, dev_trees, test_trees
  
imports: from collections import defaultdict, deque, namedtuple
  import itertools
  import os
  import re
  import sys
  from tqdm import tqdm
  from stanza.models.constituency.tree_reader import read_trees, UnclosedTreeError, ExtraCloseTreeError
  from stanza.server import tsurgeon
  from stanza.utils.conll import CoNLL
  from stanza.utils.datasets.constituency.utils import SHARDS, write_dataset
  import stanza.utils.default_paths
label_desc: Use image node_id 12 for calling a global function with example usage: read_updated_trees(paths, debug_sentence) and returns: train_trees,  dev_trees,  test_trees