static GraphDescription create(Graph graph) {
   if (graph == null) {
     return EMPTY;
   }
   Map<String, NODE> nodes = new HashMap<String, NODE>();
   for (NODE node : graph.nodes()) {
     if (nodes.put(defined(node.name()), node) != null) {
       throw new IllegalArgumentException("Node \"" + node.name() + "\" defined more than once");
     }
   }
   Map<String, REL> rels = new HashMap<String, REL>();
   List<REL> relationships = new ArrayList<REL>();
   for (REL rel : graph.relationships()) {
     createIfAbsent(nodes, rel.start());
     createIfAbsent(nodes, rel.end());
     String name = rel.name();
     if (!name.equals("")) {
       if (rels.put(name, rel) != null) {
         throw new IllegalArgumentException(
             "Relationship \"" + name + "\" defined more than once");
       }
     }
     relationships.add(rel);
   }
   parse(graph.value(), nodes, relationships);
   return new GraphDescription(
       nodes.values().toArray(NO_NODES),
       relationships.toArray(NO_RELS),
       graph.autoIndexNodes(),
       graph.autoIndexRelationships());
 }
 @Override
 public Map<String, Node> create(GraphDatabaseService graphdb) {
   Map<String, Node> result = new HashMap<String, Node>();
   Transaction tx = graphdb.beginTx();
   try {
     graphdb.index().getRelationshipAutoIndexer().setEnabled(autoIndexRelationships);
     for (NODE def : nodes) {
       result.put(
           def.name(),
           init(
               graphdb.createNode(),
               def.setNameProperty() ? def.name() : null,
               def.properties(),
               graphdb.index().getNodeAutoIndexer(),
               autoIndexNodes));
     }
     for (REL def : rels) {
       init(
           result
               .get(def.start())
               .createRelationshipTo(
                   result.get(def.end()), DynamicRelationshipType.withName(def.type())),
           def.setNameProperty() ? def.name() : null,
           def.properties(),
           graphdb.index().getRelationshipAutoIndexer(),
           autoIndexRelationships);
     }
     tx.success();
   } finally {
     tx.finish();
   }
   return result;
 }
  /**
   * Gathers all LINKS we can travel through from 'searchNode'.
   *
   * @param graph
   * @param searchNode
   * @return
   */
  protected Collection<LINK> getLinks(SEARCH_NODE searchNode) {
    NODE node = (NODE) searchNode.node;
    Collection<LINK> origLinks = (Collection<LINK>) node.getLinks();

    if (view == null) {
      return origLinks;
    }

    NODE from = (NODE) searchNode.node;

    Collection<LINK> extraLinks = view.getExtraLinks(searchNode, origLinks);

    List<LINK> result =
        new ArrayList<LINK>(origLinks.size() + (extraLinks == null ? 0 : extraLinks.size()));

    if (origLinks != null) {
      for (LINK link : origLinks) {
        if (view == null || !view.isLinkOpened(from, link)) continue;
        // LINK IS OPENED
        result.add(link);
      }
    }

    if (extraLinks != null) {
      for (LINK link : extraLinks) {
        if (view == null || !view.isLinkOpened(from, link)) continue;
        // LINK IS OPENED
        result.add(link);
      }
    }

    return result;
  }
 /**
  * Rotate the tree right at `h`.
  *
  * @param h A node.
  * @return The rotated node that replaces `h`.
  */
 protected NODE rotateRight(NODE h) {
   NODE x = h.left;
   h.left = x.right;
   x.right = h;
   x.size = h.size;
   h.size = 1 + size(h.left) + size(h.right);
   return x;
 }
 @Override
 public String getName() {
   if (DBeaverCore.getGlobalPreferenceStore()
       .getBoolean(DBeaverPreferences.NAVIGATOR_EDITOR_FULL_NAME)) {
     return node.getNodeFullName();
   } else {
     return node.getName();
   }
 }
 @Override
 public DBSDataSourceContainer getDataSourceContainer() {
   if (executionContext != null) {
     return executionContext.getDataSource().getContainer();
   } else if (node instanceof DBNDataSource) {
     return node.getDataSourceContainer();
   } else {
     return null;
   }
 }
 protected NODE put(NODE node, K key, V value) {
   if (node == null) {
     // We've reached a leaf. Create a new node to store the new value.
     return createNode(key, value);
   }
   int cmp = key.compareTo(node.key);
   if (cmp < 0) {
     // Key is less than the node. Update the left subtree.
     node.left = put(node.left, key, value);
     node.size = size(node.left) + size(node.right) + 1;
     return node;
   } else if (cmp > 0) {
     // Key is greater than the node. Update the right subtree.
     node.right = put(node.right, key, value);
     node.size = size(node.left) + size(node.right) + 1;
     return node;
   } else {
     // Update the value on the node.
     node.value = value;
     return node;
   }
 }
 protected DatabaseEditorInput(NODE node, DBECommandContext commandContext) {
   this.node = node;
   DBPDataSource dataSource = node.getDataSource();
   if (dataSource != null) {
     this.executionContext = dataSource.getDefaultContext(false);
     this.commandContext =
         commandContext != null
             ? commandContext
             : new SimpleCommandContext(this.executionContext, false);
   } else {
     this.executionContext = null;
     this.commandContext = null;
   }
 }
 protected NODE delete(NODE node, K key) {
   if (node == null) {
     // We've reached a leaf. Nothing to delete.
     return null;
   }
   int cmp = key.compareTo(node.key);
   if (cmp < 0) {
     // Key is less than the node. Delete in the left subtree.
     node.left = delete(node.left, key);
     node.size = size(node.left) + size(node.right) + 1;
     return node;
   } else if (cmp > 0) {
     // Key is greater than the node. Delete in the right subtree.
     node.right = delete(node.right, key);
     node.size = size(node.left) + size(node.right) + 1;
     return node;
   } else {
     // Delete the node.
     if (node.left == null) {
       // Replace node with its right subtree.
       return node.right;
     } else if (node.right == null) {
       // Replace node with its left subtree.
       return node.left;
     } else if (node.right.left == null) {
       // Replace node with its right subtree.
       // Move the left subtree to the right node.
       node.right.left = node.left;
       node.right.size += size(node.left);
       return node.right;
     } else {
       // Replace node with its successor (Hibbard).
       NODE s = min(node.right);
       NODE x = delete(node, s.key);
       node.key = s.key;
       node.value = s.value;
       return x;
     }
   }
 }
 @Override
 public ImageDescriptor getImageDescriptor() {
   return DBeaverIcons.getImageDescriptor(node.getNodeIconDefault());
 }
 @Override
 public DBSObject getDatabaseObject() {
   return node.getObject();
 }
 @Override
 public String getToolTipText() {
   return node.getNodeDescription();
 }