// in this function we will check if this employee can
 // process or some other action is needed
 void HR_onLeaveApplied(Employee e, Leave l)
 {
     // check if we can process this request
     if (l.NumberOfDays < MAX_LEAVES_CAN_APPROVE)
     {
         // process it on our level only
         ApproveLeave(l);
     }
     else
     {
         // if we cant process pass on to the supervisor
         // so that he can process
         if (Supervisor != null)
         {
             Supervisor.LeaveApplied(this, l);
         }
         else
         {
             // There is no one up in hierarchy so lets
             // tell the user what he needs to do now
             Console.WriteLine("Leave application suspended, Please contact HR");
         }
     }
 }
 // If we can process lets show the output
 public override void ApproveLeave(Leave leave)
 {
     Console.WriteLine("LeaveID: {0} Days: {1} Approver: {2}", leave.LeaveId, leave.NumberOfDays, "HR");
 }
 // This is the function which concrete handlers will use to take
 // action, if they are able to take actions.
 public abstract void ApproveLeave(Leave leave);
 // Using this we can apply for leave
 public void ApplyLeave(Leave leave)
 {
     LeaveApplied(this, leave);
 }
 // This will invoke events when the leave will be applied
 // i.e. the actual item will be handed over to the hierarchy of
 // concrete handlers.
 public void LeaveApplied(Employee employee, Leave leave)
 {
     onLeaveApplied?.Invoke(this, leave);
 }