@Override
 public void removeTunnel(final Requests request, final PccSession session) {
   final PlspId plspId = request.getLsp().getPlspId();
   final Tunnel tunnel = this.tunnels.get(plspId);
   final long srpId = request.getSrp().getOperationId().getValue();
   if (tunnel != null) {
     if (tunnel.getType() == LspType.PCE_LSP) {
       if (hasDelegation(tunnel, session)) {
         this.tunnels.remove(plspId);
         sendToAll(
             tunnel,
             plspId,
             tunnel.getLspState().getEro().getSubobject(),
             new SrpBuilder(request.getSrp())
                 .addAugmentation(Srp1.class, new Srp1Builder().setRemove(true).build())
                 .build(),
             reqToRptPath(request),
             request.getLsp());
       } else {
         session.sendError(
             MsgBuilderUtil.createErrorMsg(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, srpId));
       }
     } else {
       session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.LSP_NOT_PCE_INITIATED, srpId));
     }
   } else {
     session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.UNKNOWN_PLSP_ID, srpId));
   }
 }
 @Override
 public void returnDelegation(final Updates update, final PccSession session) {
   final PlspId plspId = update.getLsp().getPlspId();
   final Tunnel tunnel = this.tunnels.get(plspId);
   final long srpId = update.getSrp().getOperationId().getValue();
   if (tunnel != null) {
     // check if session really has a delegation
     if (hasDelegation(tunnel, session)) {
       // send report D=0
       final Tlvs tlvs =
           createLspTlvs(
               plspId.getValue(),
               true,
               getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), this.address),
               this.address,
               this.address,
               Optional.of(tunnel.getPathName()));
       session.sendReport(
           createPcRtpMessage(
               new LspBuilder(update.getLsp())
                   .setSync(true)
                   .setOperational(OperationalStatus.Up)
                   .setDelegate(false)
                   .setTlvs(tlvs)
                   .build(),
               Optional.of(createSrp(srpId)),
               tunnel.getLspState()));
       // start state timer
       startStateTimeout(tunnel, plspId);
       // if PCC's LSP, start re-delegation timer
       if (tunnel.getType() == LspType.PCC_LSP) {
         startRedelegationTimer(tunnel, plspId, session);
       } else {
         // if PCE-initiated LSP, revoke delegation instantly
         setDelegation(plspId, null);
       }
     } else {
       session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.UPDATE_REQ_FOR_NON_LSP, srpId));
     }
   } else {
     session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.UNKNOWN_PLSP_ID, srpId));
   }
 }
 @Override
 public synchronized void onSessionUp(final PccSession session) {
   // first session - delegate all PCC's LSPs
   // only when reporting at startup
   if (!this.sessions.containsKey(session.getId()) && session.getId() == 0) {
     for (final PlspId plspId : this.tunnels.keySet()) {
       setDelegation(plspId, session);
     }
   }
   this.sessions.put(session.getId(), session);
   if (!this.tunnels.isEmpty()) {
     // report all known LSPs
     for (final Entry<PlspId, Tunnel> entry : this.tunnels.entrySet()) {
       final Tunnel tunnel = entry.getValue();
       final boolean delegation = hasDelegation(tunnel, session);
       if (delegation) {
         tunnel.cancelTimeouts();
       }
       final long plspId = entry.getKey().getValue();
       final Tlvs tlvs =
           MsgBuilderUtil.createLspTlvs(
               plspId,
               true,
               getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), this.address),
               this.address,
               this.address,
               Optional.of(tunnel.getPathName()));
       session.sendReport(
           createPcRtpMessage(
               createLsp(plspId, true, Optional.<Tlvs>fromNullable(tlvs), delegation, false),
               NO_SRP,
               tunnel.getLspState()));
     }
     // end-of-sync marker
     session.sendReport(
         createPcRtpMessage(
             createLsp(0, false, Optional.<Tlvs>absent(), true, false),
             NO_SRP,
             createPath(Collections.<Subobject>emptyList())));
   }
 }
 @Override
 public void takeDelegation(final Requests request, final PccSession session) {
   final PlspId plspId = request.getLsp().getPlspId();
   final Tunnel tunnel = this.tunnels.get(plspId);
   final long srpId = request.getSrp().getOperationId().getValue();
   if (tunnel != null) {
     // check if tunnel has no delegation
     if (tunnel.type == LspType.PCE_LSP
         && (tunnel.getDelegationHolder() == -1
             || tunnel.getDelegationHolder() == session.getId())) {
       // set delegation
       tunnel.cancelTimeouts();
       setDelegation(plspId, session);
       // send report
       final Tlvs tlvs =
           createLspTlvs(
               plspId.getValue(),
               true,
               getDestinationAddress(tunnel.getLspState().getEro().getSubobject(), this.address),
               this.address,
               this.address,
               Optional.of(tunnel.getPathName()));
       session.sendReport(
           createPcRtpMessage(
               new LspBuilder(request.getLsp())
                   .setSync(true)
                   .setOperational(OperationalStatus.Up)
                   .setDelegate(true)
                   .setTlvs(tlvs)
                   .build(),
               Optional.of(createSrp(srpId)),
               tunnel.getLspState()));
     } else {
       session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.LSP_NOT_PCE_INITIATED, srpId));
     }
   } else {
     session.sendError(MsgBuilderUtil.createErrorMsg(PCEPErrors.UNKNOWN_PLSP_ID, srpId));
   }
 }
 @Override
 public void addTunnel(final Requests request, final PccSession session) {
   final PlspId plspId = new PlspId(this.plspIDsCounter.incrementAndGet());
   final Tunnel tunnel =
       new Tunnel(
           request.getLsp().getTlvs().getSymbolicPathName().getPathName().getValue(),
           session.getId(),
           LspType.PCE_LSP,
           reqToRptPath(request));
   sendToAll(
       tunnel,
       plspId,
       request.getEro().getSubobject(),
       createSrp(request.getSrp().getOperationId().getValue()),
       tunnel.getLspState(),
       new LspBuilder(request.getLsp())
           .addAugmentation(Lsp1.class, new Lsp1Builder().setCreate(true).build())
           .build());
   this.tunnels.put(plspId, tunnel);
 }