docs: @Override
      public synchronized ChannelData removeChannel(String channelName) throws ChannelException, ChainException {
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.entry(tc, "removeChannel: " + channelName);
          }
          if (null == channelName) {
              throw new InvalidChannelNameException("Input channel name is null");
          }
  
          // Fetch the channel data from the framework.
          ChannelDataImpl channelData = (ChannelDataImpl) channelDataMap.get(channelName);
          if (null == channelData) {
              if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
                  // Due to timing windows (i.e. multiple channel providers going away), there is
                  // a race to stop and/or clean up chains. This is not a notable condition: the chain can only be removed
                  // once.
                  Tr.exit(tc, "removeChannel: " + channelName, "Channel not found");
              }
              return null;
          }
  
          // Channel configs can only be removed if they are not in use by the
          // runtime.
          if (0 != channelData.getNumChildren()) {
              throw new ChannelException("Can't remove channel config " + channelName + " in runtime.  Destroy must happen first. ");
          }
  
          // Remove the chain config from the framework's map.
          this.channelDataMap.remove(channelName);
  
          // iterating chain configs will clear out live chains/channelRunningMap
          // Remove any chain configurations that refer to this channel.
          // Get a temp array so we can release the lock needed by removeChain.
          // This isn't a clone, but we should be okay holding the references.
          Object[] chainDataArray = this.chainDataMap.values().toArray();
          ChainDataImpl chainData = null;
          for (int i = 0; i < chainDataArray.length; i++) {
              chainData = (ChainDataImpl) chainDataArray[i];
              if (chainData.containsChannel(channelName)) {
                  // Found reference to channel config. Remove chain config.
                  // This ripples into the chain groups and cleans them up too.
                  removeChain(chainData.getName());
              }
          }
  
          if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) {
              Tr.exit(tc, "removeChannel");
          }
          return channelData;
      }