public CallerChain DecodeChain(byte[] encoded)
 {
     try {
         VersionedData[] versions = DecodeExportedVersions(encoded,
                                                           _magicTagCallChain);
         CallerChainImpl decodedChain = null;
         for (int i = 0; i < versions.Length; i++)
         {
             // Se houver duas versões, a versão atual virá antes da versão legacy.
             if (versions[i].version == ExportVersion.ConstVal)
             {
                 TypeCode signedDataTypeCode =
                     ORB.create_tc_for_type(typeof(SignedData));
                 SignedData exportedChain =
                     (SignedData)
                     _codec.decode_value(versions[i].encoded, signedDataTypeCode);
                 CallChain chain = CallerChainImpl.UnmarshalCallChain(exportedChain);
                 if (decodedChain == null)
                 {
                     decodedChain = new CallerChainImpl(chain.bus, chain.caller,
                                                        chain.target, chain.originators, exportedChain);
                 }
                 else
                 {
                     decodedChain.Signed.Chain = exportedChain;
                 }
             }
             if (versions[i].version == CurrentVersion.ConstVal)
             {
                 TypeCode exportedChainTypeCode =
                     ORB.create_tc_for_type(typeof(ExportedCallChain));
                 ExportedCallChain exportedChain =
                     (ExportedCallChain)
                     _codec.decode_value(versions[i].encoded, exportedChainTypeCode);
                 core.v2_0.services.access_control.CallChain chain =
                     CallerChainImpl.UnmarshalLegacyCallChain(exportedChain.signedChain);
                 if (decodedChain == null)
                 {
                     decodedChain = new CallerChainImpl(exportedChain.bus, chain.caller,
                                                        chain.target, chain.originators, exportedChain.signedChain);
                 }
                 else
                 {
                     decodedChain.Signed.LegacyChain = exportedChain.signedChain;
                 }
             }
         }
         if (decodedChain != null)
         {
             return(decodedChain);
         }
     }
     catch (GenericUserException e) {
         const string message =
             "Falha inesperada ao decodificar uma cadeia exportada.";
         Logger.Error(message, e);
         throw new InvalidEncodedStreamException(message, e);
     }
     throw new InvalidEncodedStreamException("Versão de cadeia incompatível.");
 }
 internal CallerChainImpl(AnyCredential anyCredential)
     : this()
 {
     Legacy = anyCredential.Legacy;
     if (Legacy)
     {
         core.v2_0.services.access_control.CallChain legacyChain = UnmarshalLegacyCallChain(anyCredential.LegacyChain);
         BusId       = anyCredential.Bus;
         Target      = legacyChain.target;
         Originators = new LoginInfo[legacyChain.originators.Length];
         for (int i = 0; i < legacyChain.originators.Length; i++)
         {
             Originators[i] = new LoginInfo(legacyChain.originators[i].id, legacyChain.originators[i].entity);
         }
         Caller = new LoginInfo(legacyChain.caller.id, legacyChain.caller.entity);
         Signed = new AnySignedChain(anyCredential.LegacyChain);
     }
     else
     {
         CallChain chain = UnmarshalCallChain(anyCredential.Chain);
         BusId       = chain.bus;
         Target      = chain.target;
         Originators = chain.originators;
         Caller      = chain.caller;
         Signed      = new AnySignedChain(anyCredential.Chain);
     }
 }