filemanager/bkupengine/src/CMMCScBkupStateArchiveOpActiveData.cpp
branchRCL_3
changeset 20 491b3ed49290
parent 19 95243422089a
child 21 65326cf895ed
equal deleted inserted replaced
19:95243422089a 20:491b3ed49290
     1 /*
       
     2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: CMMCScBkupStateArchiveOpActiveData implementation
       
    15 *
       
    16 *
       
    17 */
       
    18 
       
    19 #include "CMMCScBkupStateArchiveOpActiveData.h"
       
    20 
       
    21 // User includes
       
    22 #include "MMCScBkupLogger.h"
       
    23 #include "CMMCScBkupDataOwnerCollection.h"
       
    24 #include "CMMCScBkupDataOwnerInfo.h"
       
    25 #include "MMCScBkupSBEUtils.h"
       
    26 #include "CMMCScBkupArchive.h"
       
    27 #include "CMMCScBkupArchiveFooter.h"
       
    28 #include "CMMCScBkupIndexWithIdentifier.h"
       
    29 #include "MMMCScBkupArchiveDataInterface.h"
       
    30 
       
    31 // Constants
       
    32 const TInt KMMCScBkupActiveDataOwnerDelayBeforeRetry = 2 * 1000000; // 2 seconds
       
    33 const TInt KMMCScBkupNumberOfAttemptsToAllowADOToBecomeReady = 4; // corresponds to 8 seconds of waiting
       
    34 
       
    35 
       
    36 
       
    37 // ========================= MEMBER FUNCTIONS ================================
       
    38 
       
    39 // ---------------------------------------------------------------------------
       
    40 // CMMCScBkupStateArchiveOpActiveData::CMMCScBkupStateArchiveOpActiveData()
       
    41 // 
       
    42 // C++ constructor.
       
    43 // ---------------------------------------------------------------------------
       
    44 CMMCScBkupStateArchiveOpActiveData::CMMCScBkupStateArchiveOpActiveData( MMMCScBkupDriver& aDriver )
       
    45 :   CMMCScBkupStateOpAware( aDriver ), iIndexValueCurrent( -1 )
       
    46     {
       
    47     __LOG1("CMMCScBkupStateArchiveOpActiveData::CMMCScBkupStateArchiveOpActiveData() - 0x%08x", StateId().iUid );
       
    48     }
       
    49 
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // CMMCScBkupStateArchiveOpActiveData::~CMMCScBkupStateArchiveOpActiveData()
       
    53 // 
       
    54 // Destructor.
       
    55 // ---------------------------------------------------------------------------
       
    56 CMMCScBkupStateArchiveOpActiveData::~CMMCScBkupStateArchiveOpActiveData()
       
    57     {
       
    58     Cancel();
       
    59     //
       
    60     iTimer.Close();
       
    61     //
       
    62     delete iBackupTransferObject;
       
    63     delete iRestoreTransferObject;
       
    64     }
       
    65 
       
    66 
       
    67 // ---------------------------------------------------------------------------
       
    68 // CMMCScBkupStateArchiveOpActiveData::NewL()
       
    69 // 
       
    70 // 
       
    71 // ---------------------------------------------------------------------------
       
    72 CMMCScBkupStateArchiveOpActiveData* CMMCScBkupStateArchiveOpActiveData::NewL( MMMCScBkupDriver& aDriver )
       
    73     {
       
    74     CMMCScBkupStateArchiveOpActiveData* self = new(ELeave) CMMCScBkupStateArchiveOpActiveData( aDriver );
       
    75     return self;
       
    76     }
       
    77 
       
    78 
       
    79 // ---------------------------------------------------------------------------
       
    80 // CMMCScBkupStateArchiveOpActiveData::StateId()
       
    81 // 
       
    82 // 
       
    83 // ---------------------------------------------------------------------------
       
    84 TMMCScBkupStateId CMMCScBkupStateArchiveOpActiveData::StateId() const
       
    85     {
       
    86     return KMMCScBkupStateIdArchiveOpActiveData;
       
    87     }
       
    88 
       
    89 
       
    90 // ---------------------------------------------------------------------------
       
    91 // CMMCScBkupStateArchiveOpActiveData::NextStateBackupId()
       
    92 // 
       
    93 // 
       
    94 // ---------------------------------------------------------------------------
       
    95 TMMCScBkupStateId CMMCScBkupStateArchiveOpActiveData::NextStateBackupId( TBool /*aPartial*/ ) const
       
    96     {
       
    97     // If we still have unprocessed active data owners remaining, then
       
    98     // we must
       
    99     //
       
   100     // a) check their status again - to see if they are ready, then
       
   101     // b) process them once again via this method
       
   102     //
       
   103     // The 'get data owner statuses' object will trigger us again
       
   104     // when it has performed an update of all statuses
       
   105 
       
   106     // By default, we want to move onto the passive data...
       
   107     TMMCScBkupStateId nextState = KMMCScBkupStateIdArchiveOpPassiveData;
       
   108     if  (AllDataOwnersHandled() == EFalse)
       
   109         {
       
   110         // ... but we've still got at least one data owner who's not yet
       
   111         // finished preparing their data... so we have to retry
       
   112         nextState = KMMCScBkupStateIdGetDataOwnerStatuses;
       
   113         }
       
   114     //
       
   115     return nextState;
       
   116     }
       
   117 
       
   118 
       
   119 // ---------------------------------------------------------------------------
       
   120 // CMMCScBkupStateArchiveOpActiveData::NextStateRestoreId()
       
   121 // 
       
   122 // 
       
   123 // ---------------------------------------------------------------------------
       
   124 TMMCScBkupStateId CMMCScBkupStateArchiveOpActiveData::NextStateRestoreId( TBool /*aPartial*/ ) const
       
   125     {
       
   126     // If we still have unprocessed active data owners remaining, then
       
   127     // we must
       
   128     //
       
   129     // a) check their status again - to see if they are ready, then
       
   130     // b) process them once again via this method
       
   131     //
       
   132     // The 'get data owner statuses' object will trigger us again
       
   133     // when it has performed an update of all statuses
       
   134 
       
   135     // By default, we want to move onto the passive data...
       
   136     TMMCScBkupStateId nextState = KMMCScBkupStateIdArchiveOpPublicDataFiles;
       
   137     if  (AllDataOwnersHandled() == EFalse)
       
   138         {
       
   139         // ... but we've still got at least one data owner who's not yet
       
   140         // finished preparing their data... so we have to retry
       
   141         nextState = KMMCScBkupStateIdGetDataOwnerStatuses;
       
   142         }
       
   143     //
       
   144     return nextState;
       
   145     }
       
   146 
       
   147 
       
   148 // ---------------------------------------------------------------------------
       
   149 // CMMCScBkupStateArchiveOpActiveData::PerformStateInitBackupL()
       
   150 // 
       
   151 // 
       
   152 // ---------------------------------------------------------------------------
       
   153 void CMMCScBkupStateArchiveOpActiveData::PerformStateInitBackupL( TBool /*aPartial*/ )
       
   154     {
       
   155     __DEBUG_TESTING_SKIP_BACKUP_ACT_DATA;
       
   156     __LOG("CMMCScBkupStateArchiveOpActiveData::PerformStateInitBackupL() - START");
       
   157 
       
   158     iBackupTransferObject = CMMCScBkupWriteDataTransferRequest< TTransferDataType >::NewL(
       
   159                                     Driver(), 
       
   160                                     *this,
       
   161                                     EMMCScBkupOwnerDataTypeActiveData,
       
   162                                     ESIDTransferDerivedType,
       
   163                                     Driver().DrvParamsBase().ActiveTransferType()
       
   164                                     );
       
   165     CompleteSelf();
       
   166     __LOG("CMMCScBkupStateArchiveOpActiveData::PerformStateInitBackupL() - END");
       
   167     }
       
   168 
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // CMMCScBkupStateArchiveOpActiveData::PerformStateInitRestoreL()
       
   172 // 
       
   173 // 
       
   174 // ---------------------------------------------------------------------------
       
   175 void CMMCScBkupStateArchiveOpActiveData::PerformStateInitRestoreL( TBool /*aPartial*/ )
       
   176     {
       
   177     __DEBUG_TESTING_SKIP_RESTORE_ACT_DATA;
       
   178     __LOG("CMMCScBkupStateArchiveOpActiveData::PerformStateInitRestoreL() - START");
       
   179 
       
   180     iRestoreTransferObject = CMMCScBkupReadDataTransferRequest< TTransferDataType >::NewL(
       
   181                                     Driver(),
       
   182                                     EMMCScBkupOwnerDataTypeActiveData,
       
   183                                     Driver().DrvParamsBase().ActiveTransferType()
       
   184                                     );
       
   185 
       
   186     CompleteSelf();
       
   187     __LOG("CMMCScBkupStateArchiveOpActiveData::PerformStateInitRestoreL() - END");
       
   188     }
       
   189 
       
   190 
       
   191 // ---------------------------------------------------------------------------
       
   192 // CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL()
       
   193 // 
       
   194 // 
       
   195 // ---------------------------------------------------------------------------
       
   196 void CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL( TBool /*aPartial*/ )
       
   197     {
       
   198     CMMCScBkupDataOwnerCollection& dataOwners = Driver().DrvDataOwners();
       
   199     const TInt count = dataOwners.Count();
       
   200     __LOG2("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - START - iIndexValueCurrent: %d/%d", iIndexValueCurrent, count);
       
   201     //
       
   202     while ( ++iIndexValueCurrent < count )
       
   203         {
       
   204         CMMCScBkupDataOwnerInfo& owner = dataOwners.Owner(iIndexValueCurrent);
       
   205 
       
   206         // Has this data owner been processed?
       
   207         // Is the data owner even ready?
       
   208         const TBool activeDataAlreadyProcessed = owner.CompletionStatus( EMMCScBkupOwnerDataTypeActiveData );
       
   209         const TBool dataOwnerIsReady = ( owner.Status() == EDataOwnerReady || 
       
   210                                          owner.Status() == EDataOwnerReadyNoImpl );
       
   211         const TBool dataHasRealActiveData = ( owner.Status() == EDataOwnerReady );
       
   212         //
       
   213         __LOG5("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - DO: 0x%08x has status: %d, alreadyProcessed: %d, isReady: %d, dataHasRealActiveData: %d", owner.SecureId().iId, owner.Status(), activeDataAlreadyProcessed, dataOwnerIsReady, dataHasRealActiveData);
       
   214         //
       
   215         if  (!activeDataAlreadyProcessed)
       
   216             {
       
   217             __LOG("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - active data hasnt already been processed...");
       
   218             
       
   219             if  (dataOwnerIsReady)
       
   220                 {
       
   221                 __LOG("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - data owner is ready...");
       
   222                 
       
   223                 if  ( dataHasRealActiveData )
       
   224                     {
       
   225                     __LOG("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - data owner has real active data...");
       
   226 
       
   227                     // Try and obtain the active data for this client
       
   228                     __ASSERT_ALWAYS(iBackupTransferObject->IsActive() == EFalse, User::Invariant());
       
   229                     //
       
   230                     iBackupTransferObject->RequestL( owner, 
       
   231                                                     iStatus,
       
   232                                                     Driver().DrvParamsBase().DriveAndOperations() );
       
   233                     SetActive();
       
   234                     break; // while loop
       
   235                     }
       
   236                 else
       
   237                     {
       
   238                     // The data owner is a hybrid - we shouldn't request data for a data owner that 
       
   239                     // doesn't provide an active data interface callback implementation.
       
   240                     __LOG("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - DO is a hybrid - set completion status to ETrue");
       
   241                     owner.SetCompletionStatus( EMMCScBkupOwnerDataTypeActiveData, ETrue );
       
   242                     }
       
   243                 }
       
   244             else
       
   245                 {
       
   246                 // Retry a number of times, but eventually we'll give up
       
   247                 const TInt attemptsSoFar = owner.ActiveDataRetryCount();
       
   248                 owner.SetActiveDataRetryCount( attemptsSoFar + 1 );
       
   249 
       
   250                 if  ( attemptsSoFar >= KMMCScBkupNumberOfAttemptsToAllowADOToBecomeReady )
       
   251                     {
       
   252                     // Give up, this DO is taking too long
       
   253                     owner.SetCompletionStatus( EMMCScBkupOwnerDataTypeActiveData, ETrue );
       
   254                     __LOG1("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - ADO with SID: 0x%08x has taken too long to prepare, skipping", owner.SecureId().iId);
       
   255                     }
       
   256                 else
       
   257                     {
       
   258                     // DO is not yet ready, we're going to have to check its
       
   259                     // status again in a while...
       
   260                     __LOG1("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepBackupL() - attemptsSoFar %d", attemptsSoFar);
       
   261                     iAtLeastOneDataOwnerIsNotYetReady = ETrue;
       
   262                     }
       
   263                 }
       
   264             }
       
   265         }
       
   266     //
       
   267     CheckNeedToStartRetryTimerL();
       
   268     }
       
   269 
       
   270 
       
   271 // ---------------------------------------------------------------------------
       
   272 // CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepRestoreL()
       
   273 // 
       
   274 // 
       
   275 // ---------------------------------------------------------------------------
       
   276 void CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepRestoreL( TBool /*aPartial*/ )
       
   277     {
       
   278     CMMCScBkupIndexBase& indexBase = Driver().DrvArchive().Footer().IndexByType( EMMCScBkupOwnerDataTypeActiveData );
       
   279     CMMCScBkupIndexWithIdentifier< TSecureId >& index = static_cast< CMMCScBkupIndexWithIdentifier< TSecureId >& >( indexBase );
       
   280     const TInt count = index.Count();
       
   281     //
       
   282     //
       
   283     while ( ++iIndexValueCurrent < count )
       
   284         {
       
   285          // Get the associated data owner
       
   286         const CMMCScBkupIndexEntry<TSecureId>& entry = index.At( iIndexValueCurrent );
       
   287         CMMCScBkupDataOwnerCollection& dataOwners = Driver().DrvDataOwners();
       
   288         CMMCScBkupDataOwnerInfo& owner = dataOwners.OwnerL( entry.Identifier() );
       
   289 
       
   290         // Has this data owner been processed?
       
   291         // Is the data owner even ready?
       
   292         const TBool activeDataAlreadyProcessed = owner.CompletionStatus(EMMCScBkupOwnerDataTypeActiveData);
       
   293         const TBool dataOwnerIsReady = ( owner.Status() == EDataOwnerReady || 
       
   294                                          owner.Status() == EDataOwnerReadyNoImpl );
       
   295         //
       
   296         if  (!activeDataAlreadyProcessed)
       
   297             {
       
   298             if  (dataOwnerIsReady)
       
   299                 {
       
   300                 __ASSERT_ALWAYS(iRestoreTransferObject->IsActive() == EFalse, User::Invariant());
       
   301                 //
       
   302                 const RArray<TMMCScBkupArchiveDriveAndVector>& subEntries = entry.Entries();
       
   303                 iRestoreTransferObject->RequestL( owner, 
       
   304                                                 iStatus,
       
   305                                                 subEntries );
       
   306                 __LOG1("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepRestoreL() - trying to restore ACTIVE DATA for SID: 0x%08x", owner.SecureId().iId );
       
   307                 //
       
   308                 SetActive();
       
   309                 break; // while loop
       
   310                 }
       
   311             else
       
   312                 {
       
   313                 // Retry a number of times, but eventually we'll give up
       
   314                 const TInt attemptsSoFar = owner.ActiveDataRetryCount();
       
   315                 owner.SetActiveDataRetryCount( attemptsSoFar + 1 );
       
   316 
       
   317                 if  ( attemptsSoFar >= KMMCScBkupNumberOfAttemptsToAllowADOToBecomeReady )
       
   318                     {
       
   319                     // Give up, this DO is taking too long
       
   320                     owner.SetCompletionStatus( EMMCScBkupOwnerDataTypeActiveData, ETrue );
       
   321                     __LOG1("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousStateStepRestoreL() - ADO with SID: 0x%08x has taken too long to prepare, skipping", owner.SecureId().iId);
       
   322                     }
       
   323                 else
       
   324                     {
       
   325                     // DO is not yet ready, we're going to have to check its
       
   326                     // status again in a while...
       
   327                     iAtLeastOneDataOwnerIsNotYetReady = ETrue;
       
   328                     }
       
   329                 }
       
   330             }
       
   331         }
       
   332     //
       
   333     CheckNeedToStartRetryTimerL();
       
   334     }
       
   335 
       
   336 
       
   337 // ---------------------------------------------------------------------------
       
   338 // CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousErrorCleanupBackup()
       
   339 // 
       
   340 // 
       
   341 // ---------------------------------------------------------------------------
       
   342 TBool CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousErrorCleanupBackup( TBool /*aPartial*/, TInt aError )
       
   343     {
       
   344     (void) aError;
       
   345     __LOG1("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousErrorCleanupBackup() - **** - error: %d", aError );
       
   346 
       
   347     // Reset state and move to next item. Treat the current (badly behaving) item
       
   348     // as completed/processed.
       
   349     CMMCScBkupDataOwnerCollection& dataOwners = Driver().DrvDataOwners();
       
   350     if  ( iIndexValueCurrent < dataOwners.Count() )
       
   351         {
       
   352         CMMCScBkupDataOwnerInfo& owner = dataOwners.Owner( iIndexValueCurrent );
       
   353         owner.SetCompletionStatus( EMMCScBkupOwnerDataTypeActiveData, ETrue );
       
   354 
       
   355         __LOGFILE2("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousErrorCleanupBackup() - **** - error: %d, SID: 0x%08x - ACTIVE data skipped for DO", aError, owner.SecureId().iId );
       
   356         }
       
   357 
       
   358     CompleteSelf();
       
   359     return ETrue;
       
   360     }
       
   361 
       
   362 
       
   363 // ---------------------------------------------------------------------------
       
   364 // CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousErrorCleanupRestore()
       
   365 // 
       
   366 // 
       
   367 // ---------------------------------------------------------------------------
       
   368 TBool CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousErrorCleanupRestore( TBool /*aPartial*/, TInt aError )
       
   369     {
       
   370     (void) aError;
       
   371     __LOGFILE1("CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousErrorCleanupRestore() - **** - error: %d", aError );
       
   372 
       
   373     CompleteSelf();
       
   374     return ETrue;
       
   375     }
       
   376 
       
   377 
       
   378 // ---------------------------------------------------------------------------
       
   379 // CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousCancellation()
       
   380 // 
       
   381 // 
       
   382 // ---------------------------------------------------------------------------
       
   383 void CMMCScBkupStateArchiveOpActiveData::PerformAsynchronousCancellation()
       
   384     {
       
   385     if  (iTimer.Handle() != KNullHandle )
       
   386         {
       
   387         iTimer.Cancel();
       
   388         }
       
   389     if  (iBackupTransferObject)
       
   390         {
       
   391         iBackupTransferObject->Cancel();
       
   392         }
       
   393     if  (iRestoreTransferObject)
       
   394         {
       
   395         iRestoreTransferObject->Cancel();
       
   396         }
       
   397     }
       
   398 
       
   399 
       
   400 // ---------------------------------------------------------------------------
       
   401 // CMMCScBkupStateArchiveOpActiveData::PerformLastRightsBackupL()
       
   402 // 
       
   403 // 
       
   404 // ---------------------------------------------------------------------------
       
   405 void CMMCScBkupStateArchiveOpActiveData::PerformLastRightsBackupL( TBool /*aPartial*/ )
       
   406     {
       
   407     __LOG1("CMMCScBkupStateArchiveOpActiveData::PerformLastRightsBackupL() - iAtLeastOneDataOwnerIsNotYetReady %d", iAtLeastOneDataOwnerIsNotYetReady );
       
   408     
       
   409     if  ( AllDataOwnersHandled() )
       
   410         {
       
   411         // Only write the index if we've handled all the active data owners
       
   412         CMMCScBkupIndexBase& index = Driver().DrvArchive().Footer().IndexByType( EMMCScBkupOwnerDataTypeActiveData );
       
   413         index.StoreL(Driver());
       
   414         }
       
   415     }
       
   416 
       
   417 
       
   418 // ---------------------------------------------------------------------------
       
   419 // CMMCScBkupStateArchiveOpActiveData::AddIndexRecordL()
       
   420 // 
       
   421 // 
       
   422 // ---------------------------------------------------------------------------
       
   423 void CMMCScBkupStateArchiveOpActiveData::AddIndexRecordL( CMMCScBkupArchiveFooter& aFooter, CMMCScBkupDataOwnerInfo& aDataOwner, const TMMCScBkupArchiveVector& aInfo, TDriveNumber aDrive )
       
   424     {
       
   425     CMMCScBkupIndexBase& indexBase = aFooter.IndexByType( EMMCScBkupOwnerDataTypeActiveData );
       
   426     CMMCScBkupIndexWithIdentifier< TSecureId>& index = static_cast< CMMCScBkupIndexWithIdentifier< TSecureId>& >( indexBase );
       
   427     //
       
   428     index.AddIndexRecordL( aInfo, aDrive, aDataOwner.SecureId() );
       
   429     }
       
   430 
       
   431 
       
   432 // ---------------------------------------------------------------------------
       
   433 // CMMCScBkupStateArchiveOpActiveData::CheckNeedToStartRetryTimerL()
       
   434 // 
       
   435 // 
       
   436 // ---------------------------------------------------------------------------
       
   437 void CMMCScBkupStateArchiveOpActiveData::CheckNeedToStartRetryTimerL()
       
   438     {
       
   439     // We need to delay until the remaining active data owners are ready
       
   440     const TBool processingDataHandler = IsActive();
       
   441     if  ( !processingDataHandler && !AllDataOwnersHandled() && iTimer.Handle() == KNullHandle )
       
   442         {
       
   443         // Implicitly, we have at least one DO that's not yet ready, and 
       
   444         // we have processed as many of the ready DO's as is possible on this
       
   445         // cycle. Let's wait a few seconds to give the DO's a time to finish
       
   446         // preparing and then try again. See NextStateId() for how this works.
       
   447         User::LeaveIfError( iTimer.CreateLocal() );
       
   448 
       
   449         __LOG("CMMCScBkupStateArchiveOpActiveData::CheckNeedToStartRetryTimerL() - SetActive");
       
   450         SetActive();
       
   451         const TTimeIntervalMicroSeconds32 delay(KMMCScBkupActiveDataOwnerDelayBeforeRetry);
       
   452         iTimer.After( iStatus, delay );
       
   453         }
       
   454     }
       
   455 
       
   456 
       
   457 
       
   458 
       
   459 
       
   460 
       
   461 
       
   462 
       
   463 
       
   464 
       
   465 
       
   466 
       
   467