@Override
  public T set(int index, T value) {
    if (value == null) {
      throw new NullPointerException("A NodeList must not contain a null element!");
    } else {
      switch (value.getNodeType()) {
        case AstNode.NT_NODE_LIST:
          throw new IllegalArgumentException("Must not set a single element to a NodeList");

        case AstNode.NT_TEXT:
          return setTextIntern(children, index, (AstStringNode<T>) value);

        default:
          return children.set(index, value);
      }
    }
  }
 @SuppressWarnings("unchecked")
 private void addTextIntern(AstStringNode<T> text) {
   if (!text.getContent().isEmpty()) {
     if (i.hasPrevious() && !text.hasAttributes()) {
       T prev = i.previous();
       if (prev.getNodeType() == AstNode.NT_TEXT && !prev.hasAttributes()) {
         try {
           i.set((T) mergeTextNodes((AstStringNode<T>) prev, text));
           i.next();
           return;
         } catch (CloneNotSupportedException e) {
           // Just add, don't merge
         }
       }
     }
     i.add((T) text);
   }
 }
    @Override
    public void add(T e) {
      if (e != null) {
        current = null;
        switch (e.getNodeType()) {
          case AstNode.NT_NODE_LIST:
            for (T n : (AstNodeList<T>) e) i.add(n);
            break;

          case AstNode.NT_TEXT:
            addTextIntern((AstStringNode<T>) e);
            break;

          default:
            i.add(e);
            break;
        }
      }
    }
    @Override
    public void set(T e) {
      if (e == null) {
        throw new NullPointerException("A NodeList must not contain a null element!");
      } else {
        switch (e.getNodeType()) {
          case AstNode.NT_NODE_LIST:
            throw new IllegalArgumentException("Must not set a single element to a NodeList");

          case AstNode.NT_TEXT:
            setTextIntern((AstStringNode<T>) e);
            break;

          default:
            i.set(e);
            current = e;
            break;
        }
      }
    }
  protected void initConfig() {
    application.setEventCenter(eventCenterFactory.getEventCenter(config));

    application.setCommandBodyWrapper(new CommandBodyWrapper(config));
    application.setMasterElector(new MasterElector(application));
    application.getMasterElector().addMasterChangeListener(masterChangeListeners);
    application.setRegistryStatMonitor(new RegistryStatMonitor(application));

    node = NodeFactory.create(getNodeClass(), config);
    config.setNodeType(node.getNodeType());

    LOGGER.info("Current node config :{}", config);

    // 订阅的node管理
    SubscribedNodeManager subscribedNodeManager = new SubscribedNodeManager(application);
    application.setSubscribedNodeManager(subscribedNodeManager);
    nodeChangeListeners.add(subscribedNodeManager);
    // 用于master选举的监听器
    nodeChangeListeners.add(new MasterElectionListener(application));
    // 监听自己节点变化(如,当前节点被禁用了)
    nodeChangeListeners.add(new SelfChangeListener(application));
  }
    /** This whole method breaks the set() interface established by the ListIterator class! */
    @SuppressWarnings("unchecked")
    private void setTextIntern(AstStringNode<T> text) {
      if (current == null) throw new IllegalStateException();

      if (text.getContent().isEmpty()) {
        i.remove();
        current = null;
      } else {
        if (i.hasPrevious() && !text.hasAttributes()) {
          i.previous();
          if (i.hasPrevious()) {
            T prev = i.previous();
            if (prev.getNodeType() == AstNode.NT_TEXT && !prev.hasAttributes()) {
              try {
                i.set((T) mergeTextNodes((AstStringNode<T>) prev, text));
                // set() protocol requires that the iterator doesn't
                // move. When deleting something that's not
                // possible. So we move to the merged text element.
                i.next();
                i.next();
                i.remove();
                i.previous();
                // use own method to set current!
                next();
                return;
              } catch (CloneNotSupportedException e) {
                // Just set, don't merge
              }
            }
            i.next();
          }
          i.next();
        }
        i.set((T) text);
      }
    }