class BasicPceccHandler {

   public void releaseLabel(Tunnel tunnel) {
       boolean isLastLabelToPush = false;

       checkNotNull(labelRsrcService, LABEL_RESOURCE_SERVICE_NULL);
       checkNotNull(pceStore, PCE_STORE_NULL);

       Multimap<DeviceId, LabelResource> release = ArrayListMultimap.create();
       PceccTunnelInfo pceccTunnelInfo = pceStore.getTunnelInfo(tunnel.tunnelId());
       if (pceccTunnelInfo != null) {
           List<LspLocalLabelInfo> lspLocalLabelInfoList = pceccTunnelInfo.lspLocalLabelInfoList();
           if ((lspLocalLabelInfoList != null) && (lspLocalLabelInfoList.size() > 0)) {
               for (Iterator<LspLocalLabelInfo> iterator = lspLocalLabelInfoList.iterator(); iterator.hasNext();) {
                   LspLocalLabelInfo lspLocalLabelInfo = iterator.next();
                   DeviceId deviceId = lspLocalLabelInfo.deviceId();
                   LabelResourceId inLabelId = lspLocalLabelInfo.inLabelId();
                   LabelResourceId outLabelId = lspLocalLabelInfo.outLabelId();
                   PortNumber inPort = lspLocalLabelInfo.inPort();
                   PortNumber outPort = lspLocalLabelInfo.outPort();

                   // Check whether this is last link label to push
                   if (!iterator.hasNext()) {
                      isLastLabelToPush = true;
                   }

                   // Push into device
                   if ((inLabelId != null) && (inPort != null)) {
                       installLocalLabelRule(deviceId, inLabelId, inPort, tunnel.tunnelId(), isLastLabelToPush,
                                             Long.valueOf(LabelType.IN_LABEL.value), Objective.Operation.REMOVE);
                   }

                   if ((outLabelId != null) && (outPort != null)) {
                       installLocalLabelRule(deviceId, outLabelId, outPort, tunnel.tunnelId(), isLastLabelToPush,
                                             Long.valueOf(LabelType.OUT_LABEL.value), Objective.Operation.REMOVE);
                   }

                   // List is stored from egress to ingress. So, using IN label id to release.
                   // Only one local label is assigned to device (destination node)
                   // and that is used as OUT label for source node.
                   // No need to release label for last node in the list from pool because label was not allocated to
                   // ingress node (source node).
                   if ((iterator.hasNext()) && (inLabelId != null)) {
                       LabelResource labelRsc = new DefaultLabelResource(deviceId, inLabelId);
                       release.put(deviceId, labelRsc);
                   }
               }
           }

           // Release from label pool
           if (!release.isEmpty()) {
              labelRsrcService.releaseToDevicePool(release);
           }

           // Remove tunnel info only if tunnel consumer id is not saved.
           // If tunnel consumer id is saved, this tunnel info will be removed during releasing bandwidth.
           if (pceccTunnelInfo.tunnelConsumerId() == null) {
               pceStore.removeTunnelInfo(tunnel.tunnelId());
           }
       } else {
           log.error("Unable to find PCECC tunnel info in store for a tunnel {}.", tunnel.toString());
       }
   }

   private  BasicPceccHandler();

}